[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170914155051.8289-36-alexander.levin@verizon.com>
Date: Thu, 14 Sep 2017 15:51:15 +0000
From: "Levin, Alexander (Sasha Levin)" <alexander.levin@...izon.com>
To: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
"stable@...r.kernel.org" <stable@...r.kernel.org>
Cc: Feras Daoud <ferasda@...lanox.com>,
Erez Shitrit <erezsh@...lanox.com>,
Leon Romanovsky <leon@...nel.org>,
Doug Ledford <dledford@...hat.com>,
"Levin, Alexander (Sasha Levin)" <alexander.levin@...izon.com>
Subject: [PATCH for 4.9 36/59] IB/ipoib: Fix deadlock over vlan_mutex
From: Feras Daoud <ferasda@...lanox.com>
[ Upstream commit 1c3098cdb05207e740715857df7b0998e372f527 ]
This patch fixes Deadlock while executing ipoib_vlan_delete.
The function takes the vlan_rwsem semaphore and calls
unregister_netdevice. The later function calls
ipoib_mcast_stop_thread that cause workqueue flush.
When the queue has one of the ipoib_ib_dev_flush_xxx events,
a deadlock occur because these events also tries to catch the
same vlan_rwsem semaphore.
To fix, unregister_netdevice should be called after releasing
the semaphore.
Fixes: cbbe1efa4972 ("IPoIB: Fix deadlock between ipoib_open() and child interface create")
Signed-off-by: Feras Daoud <ferasda@...lanox.com>
Signed-off-by: Erez Shitrit <erezsh@...lanox.com>
Reviewed-by: Alex Vesker <valex@...lanox.com>
Signed-off-by: Leon Romanovsky <leon@...nel.org>
Signed-off-by: Doug Ledford <dledford@...hat.com>
Signed-off-by: Sasha Levin <alexander.levin@...izon.com>
---
drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 57eadd2b7a71..8151d1a6acb1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -193,7 +193,6 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
if (priv->pkey == pkey &&
priv->child_type == IPOIB_LEGACY_CHILD) {
- unregister_netdevice(priv->dev);
list_del(&priv->list);
dev = priv->dev;
break;
@@ -201,6 +200,11 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
}
up_write(&ppriv->vlan_rwsem);
+ if (dev) {
+ ipoib_dbg(ppriv, "delete child vlan %s\n", dev->name);
+ unregister_netdevice(dev);
+ }
+
rtnl_unlock();
if (dev) {
--
2.11.0
Powered by blists - more mailing lists