public inbox for linux-rdma@vger.kernel.org
 help / color / mirror / Atom feed
From: Denis Drozdov <denisd@mellanox.com>
To: davem@davemloft.net
Cc: jgg@ziepe.ca, dledford@redhat.com, leonro@mellanox.com,
	linux-rdma@vger.kernel.org, netdev@vger.kernel.org,
	Denis Drozdov <denisd@mellanox.com>
Subject: [PATCH net 2/2] IB/ipoib: Fix netlink support in IPoIB
Date: Sun, 31 Dec 2017 13:16:23 +0200	[thread overview]
Message-ID: <1514718983-466-3-git-send-email-denisd@mellanox.com> (raw)
In-Reply-To: <1514718983-466-1-git-send-email-denisd@mellanox.com>

IPoIB netlink support was broken by commit cd565b4b51e5
("IB/IPoIB: Support acceleration options callbacks"),
that added flow which allocates netdev rdma structures
after netlink object is already created. Such situation leads
to crash in __ipoib_device_add, once trying to reuse netlink
device.
This commit restores the netlink support.

Fixes: cd565b4b51e5 ("IB/IPoIB: Support acceleration options callbacks")
Reviewed-by: Erez Shitrit <erezsh@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Denis Drozdov <denisd@mellanox.com>
---
 drivers/infiniband/ulp/ipoib/ipoib.h         |  2 ++
 drivers/infiniband/ulp/ipoib/ipoib_main.c    | 23 +++++++++--------
 drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 38 +++++++++++++++++++++++++---
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c    | 20 ++++-----------
 4 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 8033a00..aa7a02f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -607,6 +607,8 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
 void ipoib_set_ethtool_ops(struct net_device *dev);
 void ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
 
+void ipoib_free_rdma_netdev(struct net_device *dev);
+
 #define IPOIB_FLAGS_RC		0x80
 #define IPOIB_FLAGS_UC		0x40
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 71a66a7..63c9584 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2041,6 +2041,14 @@ struct ipoib_dev_priv *ipoib_intf_alloc(struct ib_device *hca, u8 port,
 	return NULL;
 }
 
+void ipoib_free_rdma_netdev(struct net_device *dev)
+{
+	struct rdma_netdev *rn = netdev_priv(dev);
+
+	rn->free_rdma_netdev(dev);
+	kfree(ipoib_priv(dev));
+}
+
 static ssize_t show_pkey(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
@@ -2222,7 +2230,6 @@ static struct net_device *ipoib_add_port(const char *format,
 {
 	struct ipoib_dev_priv *priv;
 	struct ib_port_attr attr;
-	struct rdma_netdev *rn;
 	int result = -ENOMEM;
 
 	priv = ipoib_intf_alloc(hca, port, format);
@@ -2322,9 +2329,7 @@ static struct net_device *ipoib_add_port(const char *format,
 	ipoib_dev_cleanup(priv->dev);
 
 device_init_failed:
-	rn = netdev_priv(priv->dev);
-	rn->free_rdma_netdev(priv->dev);
-	kfree(priv);
+	ipoib_free_rdma_netdev(priv->dev);
 
 alloc_mem_failed:
 	return ERR_PTR(result);
@@ -2397,13 +2402,9 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
 
 		parent_rn->free_rdma_netdev(priv->dev);
 
-		list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
-			struct rdma_netdev *child_rn;
-
-			child_rn = netdev_priv(cpriv->dev);
-			child_rn->free_rdma_netdev(cpriv->dev);
-			kfree(cpriv);
-		}
+		list_for_each_entry_safe(cpriv, tcpriv,
+					 &priv->child_intfs, list)
+			ipoib_free_rdma_netdev(cpriv->dev);
 
 		kfree(priv);
 	}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index 3e44087..1fff706 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -93,12 +93,38 @@ static int ipoib_changelink(struct net_device *dev, struct nlattr *tb[],
 	return ret;
 }
 
+static struct net_device *ipoib_alloc_link(struct net *src_net,
+					   const char *dev_name,
+					   struct nlattr *tb[])
+{
+	struct net_device *pdev;
+	struct ipoib_dev_priv *ppriv, *priv;
+
+	if (!tb[IFLA_LINK])
+		return ERR_PTR(-EINVAL);
+
+	ASSERT_RTNL();
+	pdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
+	if (!pdev || pdev->type != ARPHRD_INFINIBAND)
+		return ERR_PTR(-ENODEV);
+
+	ppriv = ipoib_priv(pdev);
+
+	priv = ipoib_intf_alloc(ppriv->ca, ppriv->port, dev_name);
+	if (!priv) {
+		ipoib_warn(ppriv, "failed to allocate pkey device\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return priv->dev;
+}
+
 static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
 				struct nlattr *tb[], struct nlattr *data[],
 				struct netlink_ext_ack *extack)
 {
 	struct net_device *pdev;
-	struct ipoib_dev_priv *ppriv;
+	struct ipoib_dev_priv *ppriv, *priv;
 	u16 child_pkey;
 	int err;
 
@@ -131,11 +157,15 @@ static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
 	 */
 	child_pkey |= 0x8000;
 
-	err = __ipoib_vlan_add(ppriv, ipoib_priv(dev),
-			       child_pkey, IPOIB_RTNL_CHILD);
+	down_write(&ppriv->vlan_rwsem);
+
+	priv = ipoib_priv(dev);
+	err = __ipoib_vlan_add(ppriv, priv, child_pkey, IPOIB_RTNL_CHILD);
+	up_write(&ppriv->vlan_rwsem);
 
 	if (!err && data)
 		err = ipoib_changelink(dev, tb, data, extack);
+
 	return err;
 }
 
@@ -170,6 +200,8 @@ static size_t ipoib_get_size(const struct net_device *dev)
 	.dellink	= ipoib_unregister_child_dev,
 	.get_size	= ipoib_get_size,
 	.fill_info	= ipoib_fill_info,
+	.alloc_link     = ipoib_alloc_link,
+	.free_link	= ipoib_free_rdma_netdev
 };
 
 int __init ipoib_netlink_init(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 55a9b71..3ebf6de 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -162,29 +162,23 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 		result = -ENOTUNIQ;
 		goto out;
 	}
-
 	list_for_each_entry(tpriv, &ppriv->child_intfs, list) {
 		if (tpriv->pkey == pkey &&
-		    tpriv->child_type == IPOIB_LEGACY_CHILD) {
+		    (tpriv->child_type == IPOIB_LEGACY_CHILD ||
+		     tpriv->child_type == IPOIB_RTNL_CHILD)) {
 			result = -ENOTUNIQ;
 			goto out;
 		}
 	}
 
 	result = __ipoib_vlan_add(ppriv, priv, pkey, IPOIB_LEGACY_CHILD);
-
 out:
 	up_write(&ppriv->vlan_rwsem);
 	rtnl_unlock();
 	mutex_unlock(&ppriv->sysfs_mutex);
 
-	if (result && priv) {
-		struct rdma_netdev *rn;
-
-		rn = netdev_priv(priv->dev);
-		rn->free_rdma_netdev(priv->dev);
-		kfree(priv);
-	}
+	if (result && priv)
+		ipoib_free_rdma_netdev(priv->dev);
 
 	return result;
 }
@@ -235,11 +229,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 	mutex_unlock(&ppriv->sysfs_mutex);
 
 	if (dev) {
-		struct rdma_netdev *rn;
-
-		rn = netdev_priv(dev);
-		rn->free_rdma_netdev(priv->dev);
-		kfree(priv);
+		ipoib_free_rdma_netdev(dev);
 		return 0;
 	}
 
-- 
1.8.3.1

  reply	other threads:[~2017-12-31 11:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-31 11:16 [PATCH net 0/2] IB/ipoib: ip link support Denis Drozdov
2017-12-31 11:16 ` Denis Drozdov [this message]
     [not found]   ` <1514718983-466-3-git-send-email-denisd-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2017-12-31 20:23     ` [PATCH net 2/2] IB/ipoib: Fix netlink support in IPoIB Jason Gunthorpe
     [not found]       ` <20171231202308.GA10145-uk2M96/98Pc@public.gmane.org>
2018-01-01  6:38         ` Leon Romanovsky
     [not found] ` <1514718983-466-1-git-send-email-denisd-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2017-12-31 11:16   ` [PATCH net 1/2] rtnl: device allocation/free via rtnl_link_ops Denis Drozdov
     [not found]     ` <1514718983-466-2-git-send-email-denisd-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2018-01-01 22:43       ` [rtnl] b1585bdfb2: kernel_BUG_at_net/core/dev.c kernel test robot
2018-01-09 21:42         ` [PATCH v2 net 0/2] IB/ipoib: ip link support Denis Drozdov
     [not found]           ` <1515534167-13062-1-git-send-email-denisd-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2018-01-09 21:42             ` [PATCH v2 net 1/2] rtnl: device allocation/free via rtnl_link_ops Denis Drozdov
2018-01-09 21:42           ` [PATCH v2 net 2/2] IB/ipoib: Fix netlink support in IPoIB Denis Drozdov
2018-01-15 18:13           ` [PATCH v2 net 0/2] IB/ipoib: ip link support David Miller
     [not found]             ` <20180115.131309.1163036253579166139.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2018-01-18  4:25               ` Jason Gunthorpe
2018-05-07 17:29                 ` Or Gerlitz
2017-12-31 12:28   ` [PATCH " Or Gerlitz
     [not found]     ` <CAJ3xEMiVHc=E7=uKJ4cRRRDxjNDRKQ17=NxnYsEeXNe6-RUvvQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-01-02  7:29       ` Or Gerlitz
2018-01-02  8:44         ` Erez Shitrit
2018-01-02  9:15           ` Or Gerlitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1514718983-466-3-git-send-email-denisd@mellanox.com \
    --to=denisd@mellanox.com \
    --cc=davem@davemloft.net \
    --cc=dledford@redhat.com \
    --cc=jgg@ziepe.ca \
    --cc=leonro@mellanox.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox