[ofa-general] [PATCH v2] ipiob: fix rtnl deadlock

Eli Cohen eli at dev.mellanox.co.il
Mon Aug 11 15:35:24 PDT 2008


How about the following approach? We mark with a flag the fact that
we're being called from ipoib_stop and in that case we do not attempt
to take the lock.




 drivers/infiniband/ulp/ipoib/ipoib.h           |    1 +
 drivers/infiniband/ulp/ipoib/ipoib_main.c      |    2 ++
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    9 +++++++--
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index b0ffc9a..a2b5d8c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -92,6 +92,7 @@ enum {
 	IPOIB_FLAG_ADMIN_CM	  = 9,
 	IPOIB_FLAG_UMCAST	  = 10,
 	IPOIB_FLAG_CSUM		  = 11,
+	IPOIB_FLAG_STOPPING	  = 12,
 
 	IPOIB_MAX_BACKOFF_SECONDS = 16,
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f51201b..008b674 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -151,6 +151,7 @@ static int ipoib_stop(struct net_device *dev)
 
 	ipoib_dbg(priv, "stopping interface\n");
 
+	set_bit(IPOIB_FLAG_STOPPING, &priv->flags);
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 	napi_disable(&priv->napi);
 
@@ -182,6 +183,7 @@ static int ipoib_stop(struct net_device *dev)
 		mutex_unlock(&priv->vlan_mutex);
 	}
 
+	clear_bit(IPOIB_FLAG_STOPPING, &priv->flags);
 	return 0;
 }
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 8950e95..9b35188 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -576,9 +576,14 @@ void ipoib_mcast_join_task(struct work_struct *work)
 	priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu));
 
 	if (!ipoib_cm_admin_enabled(dev)) {
-		rtnl_lock();
+		int took_lock = 0;
+		if (!test_bit(IPOIB_FLAG_STOPPING, &priv->flags)) {
+			rtnl_lock();
+			took_lock = 1;
+		}
 		dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu));
-		rtnl_unlock();
+		if (took_lock)
+			rtnl_unlock();
 	}
 
 	ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n");
-- 
1.5.6.5




More information about the general mailing list