[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