net/mlx5e: IPoIB, Modify rdma netdev allocate and free to support PKEY
authorAlex Vesker <valex@mellanox.com>
Thu, 14 Sep 2017 15:22:50 +0000 (18:22 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Sat, 14 Oct 2017 18:22:12 +0000 (11:22 -0700)
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: Alex Vesker <valex@mellanox.com>
Reviewed-by: Erez Shitrit <erezsh@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en_common.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.h

index ece3fb147e3eee0707d67d0e4c336352edd1e066..157d0291723791d02c2ff2cd8e6f6a92b4ce6ea7 100644 (file)
@@ -134,6 +134,7 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
        mlx5_core_destroy_mkey(mdev, &res->mkey);
        mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
        mlx5_core_dealloc_pd(mdev, res->pdn);
+       memset(res, 0, sizeof(*res));
 }
 
 int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
index 70706eb70d3e6f464c3f92a538f5382e833a28d2..abf270d7f55605caeda209decf98526d04933dcc 100644 (file)
@@ -560,12 +560,13 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
                                          const char *name,
                                          void (*setup)(struct net_device *))
 {
-       const struct mlx5e_profile *profile = &mlx5i_nic_profile;
-       int nch = profile->max_nch(mdev);
+       const struct mlx5e_profile *profile;
        struct net_device *netdev;
        struct mlx5i_priv *ipriv;
        struct mlx5e_priv *epriv;
        struct rdma_netdev *rn;
+       bool sub_interface;
+       int nch;
        int err;
 
        if (mlx5i_check_required_hca_cap(mdev)) {
@@ -573,10 +574,15 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
                return ERR_PTR(-EOPNOTSUPP);
        }
 
-       /* This function should only be called once per mdev */
-       err = mlx5e_create_mdev_resources(mdev);
-       if (err)
-               return NULL;
+       /* TODO: Need to find a better way to check if child device*/
+       sub_interface = (mdev->mlx5e_res.pdn != 0);
+
+       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),
                                  name, NET_NAME_UNKNOWN,
@@ -585,7 +591,7 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
                                  nch);
        if (!netdev) {
                mlx5_core_warn(mdev, "alloc_netdev_mqs failed\n");
-               goto free_mdev_resources;
+               return NULL;
        }
 
        ipriv = netdev_priv(netdev);
@@ -595,10 +601,18 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
        if (!epriv->wq)
                goto err_free_netdev;
 
-       err = mlx5i_pkey_qpn_ht_init(netdev);
-       if (err) {
-               mlx5_core_warn(mdev, "allocate qpn_to_netdev ht failed\n");
-               goto destroy_wq;
+       ipriv->sub_interface = sub_interface;
+       if (!ipriv->sub_interface) {
+               err = mlx5i_pkey_qpn_ht_init(netdev);
+               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);
@@ -616,12 +630,12 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
 
        return netdev;
 
+destroy_ht:
+       mlx5i_pkey_qpn_ht_cleanup(netdev);
 destroy_wq:
        destroy_workqueue(epriv->wq);
 err_free_netdev:
        free_netdev(netdev);
-free_mdev_resources:
-       mlx5e_destroy_mdev_resources(mdev);
 
        return NULL;
 }
@@ -629,16 +643,18 @@ EXPORT_SYMBOL(mlx5_rdma_netdev_alloc);
 
 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;
-       struct mlx5_core_dev       *mdev    = priv->mdev;
 
        mlx5e_detach_netdev(priv);
        profile->cleanup(priv);
        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);
index a50c1a19550e19225f4677d89d6eef226aa93078..49008022c3062ec92aadb29085894b55a19f21dc 100644 (file)
@@ -50,6 +50,7 @@ extern const struct ethtool_ops mlx5i_pkey_ethtool_ops;
 struct mlx5i_priv {
        struct rdma_netdev rn; /* keep this first */
        struct mlx5_core_qp qp;
+       bool   sub_interface;
        u32    qkey;
        u16    pkey_index;
        struct mlx5i_pkey_qpn_ht *qpn_htbl;