All of lore.kernel.org
 help / color / mirror / Atom feed
From: Denis Drozdov <denisd@mellanox.com>
To: davem@davemloft.net
Cc: jgg@mellanox.com, dledford@redhat.com, leonro@mellanox.com,
	linux-rdma@vger.kernel.org, netdev@vger.kernel.org,
	gerlitz.or@gmail.com, Denis Drozdov <denisd@mellanox.com>
Subject: [PATCH v2 net 2/2] IB/ipoib: Fix netlink support in IPoIB
Date: Tue,  9 Jan 2018 23:42:47 +0200	[thread overview]
Message-ID: <1515534167-13062-3-git-send-email-denisd@mellanox.com> (raw)
In-Reply-To: <1515534167-13062-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")
Signed-off-by: Denis Drozdov <denisd@mellanox.com>
Reviewed-by: Erez Shitrit <erezsh@mellanox.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/infiniband/ulp/ipoib/ipoib.h         |  2 ++
 drivers/infiniband/ulp/ipoib/ipoib_main.c    | 23 ++++++++--------
 drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 39 +++++++++++++++++++++++++---
 drivers/infiniband/ulp/ipoib/ipoib_vlan.c    | 20 ++++----------
 4 files changed, 54 insertions(+), 30 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 8880351d..6e7548e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2022,6 +2022,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)
 {
@@ -2203,7 +2211,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);
@@ -2303,9 +2310,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);
@@ -2378,13 +2383,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..f5cbb7a 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;
 }
 
@@ -163,13 +193,14 @@ static size_t ipoib_get_size(const struct net_device *dev)
 	.kind		= "ipoib",
 	.maxtype	= IFLA_IPOIB_MAX,
 	.policy		= ipoib_policy,
-	.priv_size	= sizeof(struct ipoib_dev_priv),
 	.setup		= ipoib_setup_common,
 	.newlink	= ipoib_new_child_link,
 	.changelink	= ipoib_changelink,
 	.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

  parent reply	other threads:[~2018-01-09 21:42 UTC|newest]

Thread overview: 18+ 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
     [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-01 22:43         ` kernel test robot
2018-01-01 22:43         ` 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           ` Denis Drozdov [this message]
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
2017-12-31 11:16 ` [PATCH net 2/2] IB/ipoib: Fix netlink support in IPoIB Denis Drozdov
     [not found]   ` <1514718983-466-3-git-send-email-denisd-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
2017-12-31 20:23     ` Jason Gunthorpe
     [not found]       ` <20171231202308.GA10145-uk2M96/98Pc@public.gmane.org>
2018-01-01  6:38         ` Leon Romanovsky

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=1515534167-13062-3-git-send-email-denisd@mellanox.com \
    --to=denisd@mellanox.com \
    --cc=davem@davemloft.net \
    --cc=dledford@redhat.com \
    --cc=gerlitz.or@gmail.com \
    --cc=jgg@mellanox.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.