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 <[email protected]> --- 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); _______________________________________________ general mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general
