aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
diff options
context:
space:
mode:
authorDoug Ledford <dledford@redhat.com>2015-02-21 19:27:04 -0500
committerDoug Ledford <dledford@redhat.com>2015-04-15 16:06:18 -0400
commitefc82eeeae4ece716091d8540079b7f276ca1ad5 (patch)
tree541dfa13579f95f18e51ff5caee6f6d1fa34591d /drivers/infiniband/ulp/ipoib/ipoib_multicast.c
parentIB/ipoib: Use dedicated workqueues per interface (diff)
downloadwireguard-linux-efc82eeeae4ece716091d8540079b7f276ca1ad5.tar.xz
wireguard-linux-efc82eeeae4ece716091d8540079b7f276ca1ad5.zip
IB/ipoib: No longer use flush as a parameter
Various places in the IPoIB code had a deadlock related to flushing the ipoib workqueue. Now that we have per device workqueues and a specific flush workqueue, there is no longer a deadlock issue with flushing the device specific workqueues and we can do so unilaterally. Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_multicast.c')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 9d3c1ed576ea..bb1b69904f96 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -613,7 +613,7 @@ int ipoib_mcast_start_thread(struct net_device *dev)
return 0;
}
-int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
+int ipoib_mcast_stop_thread(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -624,8 +624,7 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
cancel_delayed_work(&priv->mcast_task);
mutex_unlock(&mcast_mutex);
- if (flush)
- flush_workqueue(priv->wq);
+ flush_workqueue(priv->wq);
return 0;
}
@@ -797,7 +796,18 @@ void ipoib_mcast_restart_task(struct work_struct *work)
ipoib_dbg_mcast(priv, "restarting multicast task\n");
- ipoib_mcast_stop_thread(dev, 0);
+ /*
+ * We're running on the priv->wq right now, so we can't call
+ * mcast_stop_thread as it wants to flush the wq and that
+ * will deadlock. We don't actually *need* to stop the
+ * thread here anyway, so just clear the run flag, cancel
+ * any delayed work, do our work, remove the old entries,
+ * then restart the thread.
+ */
+ mutex_lock(&mcast_mutex);
+ clear_bit(IPOIB_MCAST_RUN, &priv->flags);
+ cancel_delayed_work(&priv->mcast_task);
+ mutex_unlock(&mcast_mutex);
local_irq_save(flags);
netif_addr_lock(dev);