diff options
author | Doug Ledford <dledford@redhat.com> | 2015-02-21 19:27:04 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-04-15 16:06:18 -0400 |
commit | efc82eeeae4ece716091d8540079b7f276ca1ad5 (patch) | |
tree | 541dfa13579f95f18e51ff5caee6f6d1fa34591d /drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |
parent | 0b39578bcde4298a392fb2df16235c316d932127 (diff) | |
download | linux-efc82eeeae4ece716091d8540079b7f276ca1ad5.tar.bz2 |
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.c | 18 |
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); |