Commit b5ae5777 authored by Alex Vesker's avatar Alex Vesker Committed by Saeed Mahameed

net/mlx5e: IPoIB, Modify rdma netdev allocate and free to support PKEY

Resources such as FT, QPN HT and mdev resources should be allocated
only by parent netdev. Shared resources are allocated and freed by the
parent interface since the parent is always present and created
before the IPoIB PKEY sub-interface.
Signed-off-by: default avatarAlex Vesker <valex@mellanox.com>
Reviewed-by: default avatarErez Shitrit <erezsh@mellanox.com>
parent 6a910233
...@@ -134,6 +134,7 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev) ...@@ -134,6 +134,7 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
mlx5_core_destroy_mkey(mdev, &res->mkey); mlx5_core_destroy_mkey(mdev, &res->mkey);
mlx5_core_dealloc_transport_domain(mdev, res->td.tdn); mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
mlx5_core_dealloc_pd(mdev, res->pdn); mlx5_core_dealloc_pd(mdev, res->pdn);
memset(res, 0, sizeof(*res));
} }
int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
......
...@@ -560,12 +560,13 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, ...@@ -560,12 +560,13 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
const char *name, const char *name,
void (*setup)(struct net_device *)) void (*setup)(struct net_device *))
{ {
const struct mlx5e_profile *profile = &mlx5i_nic_profile; const struct mlx5e_profile *profile;
int nch = profile->max_nch(mdev);
struct net_device *netdev; struct net_device *netdev;
struct mlx5i_priv *ipriv; struct mlx5i_priv *ipriv;
struct mlx5e_priv *epriv; struct mlx5e_priv *epriv;
struct rdma_netdev *rn; struct rdma_netdev *rn;
bool sub_interface;
int nch;
int err; int err;
if (mlx5i_check_required_hca_cap(mdev)) { if (mlx5i_check_required_hca_cap(mdev)) {
...@@ -573,10 +574,15 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, ...@@ -573,10 +574,15 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
} }
/* This function should only be called once per mdev */ /* TODO: Need to find a better way to check if child device*/
err = mlx5e_create_mdev_resources(mdev); sub_interface = (mdev->mlx5e_res.pdn != 0);
if (err)
return NULL; if (sub_interface)
profile = mlx5i_pkey_get_profile();
else
profile = &mlx5i_nic_profile;
nch = profile->max_nch(mdev);
netdev = alloc_netdev_mqs(sizeof(struct mlx5i_priv) + sizeof(struct mlx5e_priv), netdev = alloc_netdev_mqs(sizeof(struct mlx5i_priv) + sizeof(struct mlx5e_priv),
name, NET_NAME_UNKNOWN, name, NET_NAME_UNKNOWN,
...@@ -585,7 +591,7 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, ...@@ -585,7 +591,7 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
nch); nch);
if (!netdev) { if (!netdev) {
mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n"); mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n");
goto free_mdev_resources; return NULL;
} }
ipriv = netdev_priv(netdev); ipriv = netdev_priv(netdev);
...@@ -595,10 +601,18 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, ...@@ -595,10 +601,18 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
if (!epriv->wq) if (!epriv->wq)
goto err_free_netdev; goto err_free_netdev;
err = mlx5i_pkey_qpn_ht_init(netdev); ipriv->sub_interface = sub_interface;
if (err) { if (!ipriv->sub_interface) {
mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n"); err = mlx5i_pkey_qpn_ht_init(netdev);
goto destroy_wq; if (err) {
mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
goto destroy_wq;
}
/* This should only be called once per mdev */
err = mlx5e_create_mdev_resources(mdev);
if (err)
goto destroy_ht;
} }
profile->init(mdev, netdev, profile, ipriv); profile->init(mdev, netdev, profile, ipriv);
...@@ -616,12 +630,12 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, ...@@ -616,12 +630,12 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
return netdev; return netdev;
destroy_ht:
mlx5i_pkey_qpn_ht_cleanup(netdev);
destroy_wq: destroy_wq:
destroy_workqueue(epriv->wq); destroy_workqueue(epriv->wq);
err_free_netdev: err_free_netdev:
free_netdev(netdev); free_netdev(netdev);
free_mdev_resources:
mlx5e_destroy_mdev_resources(mdev);
return NULL; return NULL;
} }
...@@ -629,16 +643,18 @@ EXPORT_SYMBOL(mlx5_rdma_netdev_alloc); ...@@ -629,16 +643,18 @@ EXPORT_SYMBOL(mlx5_rdma_netdev_alloc);
void mlx5_rdma_netdev_free(struct net_device *netdev) void mlx5_rdma_netdev_free(struct net_device *netdev)
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
struct mlx5i_priv *ipriv = priv->ppriv;
const struct mlx5e_profile *profile = priv->profile; const struct mlx5e_profile *profile = priv->profile;
struct mlx5_core_dev *mdev = priv->mdev;
mlx5e_detach_netdev(priv); mlx5e_detach_netdev(priv);
profile->cleanup(priv); profile->cleanup(priv);
destroy_workqueue(priv->wq); destroy_workqueue(priv->wq);
mlx5i_pkey_qpn_ht_cleanup(netdev);
free_netdev(netdev);
mlx5e_destroy_mdev_resources(mdev); if (!ipriv->sub_interface) {
mlx5i_pkey_qpn_ht_cleanup(netdev);
mlx5e_destroy_mdev_resources(priv->mdev);
}
free_netdev(netdev);
} }
EXPORT_SYMBOL(mlx5_rdma_netdev_free); EXPORT_SYMBOL(mlx5_rdma_netdev_free);
...@@ -50,6 +50,7 @@ extern const struct ethtool_ops mlx5i_pkey_ethtool_ops; ...@@ -50,6 +50,7 @@ extern const struct ethtool_ops mlx5i_pkey_ethtool_ops;
struct mlx5i_priv { struct mlx5i_priv {
struct rdma_netdev rn; /* keep this first */ struct rdma_netdev rn; /* keep this first */
struct mlx5_core_qp qp; struct mlx5_core_qp qp;
bool sub_interface;
u32 qkey; u32 qkey;
u16 pkey_index; u16 pkey_index;
struct mlx5i_pkey_qpn_ht *qpn_htbl; struct mlx5i_pkey_qpn_ht *qpn_htbl;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment