diff options
| author | Roland Dreier <roland@purestorage.com> | 2015-01-30 18:39:11 -0500 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2015-01-30 18:39:11 -0500 |
| commit | 962121b4fcd3e022c276104aec50b56d7ed1f71b (patch) | |
| tree | 3e6a7d3b1c46122b1139a2e63585d09f1f27e0fb | |
| parent | bb75963414906cf2eda59f09b42bb99f0c8c8318 (diff) | |
Revert "IPoIB: fix mcast_dev_flush/mcast_restart_task race"
This reverts commit e5d1dcf1b0951f4ba00d93653942dda6196109d8.
The series of IPoIB bug fixes that went into 3.19-rc1 introduce
regressions, and after trying to sort things out, we decided to revert
to 3.18's IPoIB driver and get things right for 3.20.
Signed-off-by: Roland Dreier <roland@purestorage.com>
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 37 |
1 files changed, 5 insertions, 32 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 41325960e4e0..a52c9f3f7e42 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
| @@ -802,10 +802,7 @@ void ipoib_mcast_dev_flush(struct net_device *dev) | |||
| 802 | 802 | ||
| 803 | spin_unlock_irqrestore(&priv->lock, flags); | 803 | spin_unlock_irqrestore(&priv->lock, flags); |
| 804 | 804 | ||
| 805 | /* | 805 | /* seperate between the wait to the leave*/ |
| 806 | * make sure the in-flight joins have finished before we attempt | ||
| 807 | * to leave | ||
| 808 | */ | ||
| 809 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) | 806 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) |
| 810 | if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) | 807 | if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) |
| 811 | wait_for_completion(&mcast->done); | 808 | wait_for_completion(&mcast->done); |
| @@ -926,38 +923,14 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
| 926 | netif_addr_unlock(dev); | 923 | netif_addr_unlock(dev); |
| 927 | local_irq_restore(flags); | 924 | local_irq_restore(flags); |
| 928 | 925 | ||
| 929 | /* | 926 | /* We have to cancel outside of the spinlock */ |
| 930 | * make sure the in-flight joins have finished before we attempt | ||
| 931 | * to leave | ||
| 932 | */ | ||
| 933 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) | ||
| 934 | if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) | ||
| 935 | wait_for_completion(&mcast->done); | ||
| 936 | |||
| 937 | /* | ||
| 938 | * We have to cancel outside of the spinlock, but we have to | ||
| 939 | * take the rtnl lock or else we race with the removal of | ||
| 940 | * entries from the remove list in mcast_dev_flush as part | ||
| 941 | * of ipoib_stop() which will call mcast_stop_thread with | ||
| 942 | * flush == 1 while holding the rtnl lock, and the | ||
| 943 | * flush_workqueue won't complete until this restart_mcast_task | ||
| 944 | * completes. So do like the carrier on task and attempt to | ||
| 945 | * take the rtnl lock, but if we can't before the ADMIN_UP flag | ||
| 946 | * goes away, then just return and know that the remove list will | ||
| 947 | * get flushed later by mcast_dev_flush. | ||
| 948 | */ | ||
| 949 | while (!rtnl_trylock()) { | ||
| 950 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) | ||
| 951 | return; | ||
| 952 | else | ||
| 953 | msleep(20); | ||
| 954 | } | ||
| 955 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { | 927 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { |
| 956 | ipoib_mcast_leave(mcast->dev, mcast); | 928 | ipoib_mcast_leave(mcast->dev, mcast); |
| 957 | ipoib_mcast_free(mcast); | 929 | ipoib_mcast_free(mcast); |
| 958 | } | 930 | } |
| 959 | ipoib_mcast_start_thread(dev); | 931 | |
| 960 | rtnl_unlock(); | 932 | if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) |
| 933 | ipoib_mcast_start_thread(dev); | ||
| 961 | } | 934 | } |
| 962 | 935 | ||
| 963 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 936 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
