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 |