[openib-general] [PATCH] ipoib: flush task race
Michael S. Tsirkin
mst at mellanox.co.il
Mon Jan 9 07:08:48 PST 2006
Fix a race in IPoIB: flush task has started runnning and the user does ifconfig
ib0 down. This results in race conditions, e.g. ipoib_mcast_stop_thread might
be waiting for the same completion in parallel on two CPUs.
Solve this by moving flush_task to ipoib_wq.
Signed-off-by: Jack Morgenstein <jackm at mellanox.co.il>
Signed-off-by: Michael S. Tsirkin <mst at mellanox.co.il>
Index: openib/drivers/infiniband/ulp/ipoib/ipoib.h
===================================================================
--- openib.orig/drivers/infiniband/ulp/ipoib/ipoib.h 2006-01-09 12:06:31.000000000 +0200
+++ openib/drivers/infiniband/ulp/ipoib/ipoib.h 2006-01-09 13:47:21.000000000 +0200
@@ -252,7 +252,7 @@ void ipoib_ib_dev_cleanup(struct net_dev
int ipoib_ib_dev_open(struct net_device *dev);
int ipoib_ib_dev_up(struct net_device *dev);
-int ipoib_ib_dev_down(struct net_device *dev);
+int ipoib_ib_dev_down(struct net_device *dev, int flush);
int ipoib_ib_dev_stop(struct net_device *dev);
int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
Index: openib/drivers/infiniband/ulp/ipoib/ipoib_ib.c
===================================================================
--- openib.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2006-01-02 11:56:50.000000000 +0200
+++ openib/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2006-01-09 13:47:21.000000000 +0200
@@ -434,7 +434,7 @@ int ipoib_ib_dev_up(struct net_device *d
return ipoib_mcast_start_thread(dev);
}
-int ipoib_ib_dev_down(struct net_device *dev)
+int ipoib_ib_dev_down(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -449,10 +449,11 @@ int ipoib_ib_dev_down(struct net_device
set_bit(IPOIB_PKEY_STOP, &priv->flags);
cancel_delayed_work(&priv->pkey_task);
up(&pkey_sem);
- flush_workqueue(ipoib_workqueue);
+ if (flush)
+ flush_workqueue(ipoib_workqueue);
}
- ipoib_mcast_stop_thread(dev, 1);
+ ipoib_mcast_stop_thread(dev, flush);
/*
* Flush the multicast groups first so we stop any multicast joins. The
@@ -599,7 +600,7 @@ void ipoib_ib_dev_flush(void *_dev)
ipoib_dbg(priv, "flushing\n");
- ipoib_ib_dev_down(dev);
+ ipoib_ib_dev_down(dev, 0);
/*
* The device could have been brought down between the start and when
Index: openib/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- openib.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c 2006-01-08 11:41:20.000000000 +0200
+++ openib/drivers/infiniband/ulp/ipoib/ipoib_main.c 2006-01-09 13:47:22.000000000 +0200
@@ -133,7 +133,7 @@ static int ipoib_stop(struct net_device
netif_stop_queue(dev);
- ipoib_ib_dev_down(dev);
+ ipoib_ib_dev_down(dev, 1);
ipoib_ib_dev_stop(dev);
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
Index: openib/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
===================================================================
--- openib.orig/drivers/infiniband/ulp/ipoib/ipoib_verbs.c 2005-12-22 16:52:33.000000000 +0200
+++ openib/drivers/infiniband/ulp/ipoib/ipoib_verbs.c 2006-01-09 13:47:22.000000000 +0200
@@ -255,6 +255,6 @@ void ipoib_event(struct ib_event_handler
record->event == IB_EVENT_LID_CHANGE ||
record->event == IB_EVENT_SM_CHANGE) {
ipoib_dbg(priv, "Port active event\n");
- schedule_work(&priv->flush_task);
+ queue_work(ipoib_workqueue, &priv->flush_task);
}
}
--
MST
More information about the general
mailing list