[ofa-general] [PATCH] ipoib: disable napi while cq is being drained

Yossi Etigin yosefe at voltaire.com
Fri Apr 10 08:45:08 PDT 2009


 If napi is enabled while cq is being drained, it creates a race on priv->ibwc
between ipoib_poll and ipoib_drain_cq, leading to memory corruption.
 The solution is to enable/disable napi in ipoib_ib_dev_open/stop instead of in
ipoib_open/stop, and sync napi on INITIALIZED bit instead on ADMIN_UP bit. This
way napi will be disabled when ipoib_drain_cq is called.

Signed-off-by: Yossi Etigin <yosefe at voltaire.com>

---
Fix bugzilla #1587.

Index: b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-04-09 13:48:27.000000000 +0300
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2009-04-10 17:58:10.000000000 +0300
@@ -685,7 +685,8 @@ int ipoib_ib_dev_open(struct net_device 
 	queue_delayed_work(ipoib_workqueue, &priv->ah_reap_task,
 			   round_jiffies_relative(HZ));
 
-	set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+	if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		napi_enable(&priv->napi);
 
 	return 0;
 }
@@ -804,7 +805,8 @@ int ipoib_ib_dev_stop(struct net_device 
 	struct ipoib_tx_buf *tx_req;
 	int i;
 
-	clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
+	if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags))
+		napi_disable(&priv->napi);
 
 	ipoib_cm_dev_stop(dev);
 
Index: b/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-04-09 15:16:24.000000000 +0300
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c	2009-04-10 18:26:11.000000000 +0300
@@ -106,8 +106,7 @@ int ipoib_open(struct net_device *dev)
 
 	ipoib_dbg(priv, "bringing up interface\n");
 
-	if (!test_and_set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
-		napi_enable(&priv->napi);
+	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 	if (ipoib_pkey_dev_delay_open(dev))
 		return 0;
@@ -143,7 +142,6 @@ err_stop:
 	ipoib_ib_dev_stop(dev, 1);
 
 err_disable:
-	napi_disable(&priv->napi);
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
 
 	return -EINVAL;
@@ -156,7 +154,6 @@ static int ipoib_stop(struct net_device 
 	ipoib_dbg(priv, "stopping interface\n");
 
 	clear_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);
-	napi_disable(&priv->napi);
 
 	netif_stop_queue(dev);
 



More information about the general mailing list