diff options
author | Erez Shitrit <erezsh@mellanox.com> | 2017-07-12 06:11:54 -0400 |
---|---|---|
committer | Leon Romanovsky <leon@kernel.org> | 2017-07-23 02:45:11 -0400 |
commit | a08e1120627f72e9ed7c291e3b9f8dd29c1513ab (patch) | |
tree | a9062a0fc6836e5df1f9495a41c60eaacafed1b3 | |
parent | 6bdc8de2e86e717124a715ecc480892a2c331ff5 (diff) |
IB/ipoib: Make sure no in-flight joins while leaving that mcast
While cleaning neighs and there is a send-only mcast neigh, the driver
should wait to finish its join process before trying to remove it.
Without this patch, we will see messages like: "ipoib_mcast_leave on an
in-flight join" and unexpected results in the join_complete.
Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index f80bf0f5d7cf..93e149efc1f5 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -743,6 +743,14 @@ void ipoib_mcast_remove_list(struct list_head *remove_list) | |||
743 | { | 743 | { |
744 | struct ipoib_mcast *mcast, *tmcast; | 744 | struct ipoib_mcast *mcast, *tmcast; |
745 | 745 | ||
746 | /* | ||
747 | * make sure the in-flight joins have finished before we attempt | ||
748 | * to leave | ||
749 | */ | ||
750 | list_for_each_entry_safe(mcast, tmcast, remove_list, list) | ||
751 | if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) | ||
752 | wait_for_completion(&mcast->done); | ||
753 | |||
746 | list_for_each_entry_safe(mcast, tmcast, remove_list, list) { | 754 | list_for_each_entry_safe(mcast, tmcast, remove_list, list) { |
747 | ipoib_mcast_leave(mcast->dev, mcast); | 755 | ipoib_mcast_leave(mcast->dev, mcast); |
748 | ipoib_mcast_free(mcast); | 756 | ipoib_mcast_free(mcast); |
@@ -852,14 +860,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev) | |||
852 | 860 | ||
853 | spin_unlock_irqrestore(&priv->lock, flags); | 861 | spin_unlock_irqrestore(&priv->lock, flags); |
854 | 862 | ||
855 | /* | ||
856 | * make sure the in-flight joins have finished before we attempt | ||
857 | * to leave | ||
858 | */ | ||
859 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) | ||
860 | if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) | ||
861 | wait_for_completion(&mcast->done); | ||
862 | |||
863 | ipoib_mcast_remove_list(&remove_list); | 863 | ipoib_mcast_remove_list(&remove_list); |
864 | mutex_unlock(&priv->mcast_mutex); | 864 | mutex_unlock(&priv->mcast_mutex); |
865 | } | 865 | } |
@@ -979,14 +979,6 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
979 | netif_addr_unlock(dev); | 979 | netif_addr_unlock(dev); |
980 | local_irq_restore(flags); | 980 | local_irq_restore(flags); |
981 | 981 | ||
982 | /* | ||
983 | * make sure the in-flight joins have finished before we attempt | ||
984 | * to leave | ||
985 | */ | ||
986 | list_for_each_entry_safe(mcast, tmcast, &remove_list, list) | ||
987 | if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) | ||
988 | wait_for_completion(&mcast->done); | ||
989 | |||
990 | ipoib_mcast_remove_list(&remove_list); | 982 | ipoib_mcast_remove_list(&remove_list); |
991 | 983 | ||
992 | /* | 984 | /* |