[openib-general] [PATCH] ipoib_mcast_restart_task
Eli Cohen
eli at mellanox.co.il
Wed Apr 5 04:59:40 PDT 2006
ipoib_mcast_restart_task might free an mcast object while a join request
is still outstanding, leading to an oops when the query completes. Fix
this by waiting for query to complete, similar to what ipoib_stop_thread is
doing. The wait for mcast completion code is consolidated in wait_join_complete().
Signed-off-by: Eli Cohen <eli at mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>
Index: latest/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
===================================================================
--- latest.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ latest/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -617,6 +617,22 @@ int ipoib_mcast_start_thread(struct net_
return 0;
}
+static void wait_join_complete(struct ipoib_dev_priv *priv,
+ struct ipoib_mcast *mcast)
+{
+ spin_lock_irq(&priv->lock);
+ if (mcast && mcast->query) {
+ ib_sa_cancel_query(mcast->query_id, mcast->query);
+ mcast->query = NULL;
+ spin_unlock_irq(&priv->lock);
+ ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
+ IPOIB_GID_ARG(mcast->mcmember.mgid));
+ wait_for_completion(&mcast->done);
+ }
+ else
+ spin_unlock_irq(&priv->lock);
+}
+
int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -636,28 +652,10 @@ int ipoib_mcast_stop_thread(struct net_d
if (flush)
flush_workqueue(ipoib_workqueue);
- spin_lock_irq(&priv->lock);
- if (priv->broadcast && priv->broadcast->query) {
- ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
- priv->broadcast->query = NULL;
- spin_unlock_irq(&priv->lock);
- ipoib_dbg_mcast(priv, "waiting for bcast\n");
- wait_for_completion(&priv->broadcast->done);
- } else
- spin_unlock_irq(&priv->lock);
+ wait_join_complete(priv, priv->broadcast);
- list_for_each_entry(mcast, &priv->multicast_list, list) {
- spin_lock_irq(&priv->lock);
- if (mcast->query) {
- ib_sa_cancel_query(mcast->query_id, mcast->query);
- mcast->query = NULL;
- spin_unlock_irq(&priv->lock);
- ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
- IPOIB_GID_ARG(mcast->mcmember.mgid));
- wait_for_completion(&mcast->done);
- } else
- spin_unlock_irq(&priv->lock);
- }
+ list_for_each_entry(mcast, &priv->multicast_list, list)
+ wait_join_complete(priv, mcast);
return 0;
}
@@ -910,6 +908,7 @@ void ipoib_mcast_restart_task(void *dev_
/* We have to cancel outside of the spinlock */
list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
+ wait_join_complete(priv, mcast);
ipoib_mcast_leave(mcast->dev, mcast);
ipoib_mcast_free(mcast);
}
More information about the general
mailing list