Moni Shoua wrote:
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 
> b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> index a0e9753..024fd18 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> @@ -379,6 +379,7 @@ static int ipoib_mcast_join_complete(int status,
>       struct ipoib_mcast *mcast = multicast->context;
>       struct net_device *dev = mcast->dev;
>       struct ipoib_dev_priv *priv = netdev_priv(dev);
> +     struct ipoib_mcast *next_mcast;
>  
>       ipoib_dbg_mcast(priv, "join completion for %pI6 (status %d)\n",
>                       mcast->mcmember.mgid.raw, status);
> @@ -427,9 +428,16 @@ static int ipoib_mcast_join_complete(int status,
>  
>       mutex_lock(&mcast_mutex);
>       spin_lock_irq(&priv->lock);
> -     if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
> -             queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
> -                                mcast->backoff * HZ);
> +     if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) {
> +             list_for_each_entry(next_mcast, &priv->multicast_list, list) {
> +                     if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, 
> &next_mcast->flags)
> +                         && !test_bit(IPOIB_MCAST_FLAG_BUSY, 
> &next_mcast->flags)
> +                         && !test_bit(IPOIB_MCAST_FLAG_ATTACHED, 
> &next_mcast->flags))
> +                             break;
> +             }
> +             queue_delayed_work(ipoib_workqueue, &priv->mcast_join_task,
> +                     next_mcast->backoff * HZ);
> +     }
>       spin_unlock_irq(&priv->lock);
>       mutex_unlock(&mcast_mutex);
>  

The scan is only done to get the backoff to use, right?

You should also check (&next_mcast->list != &priv->multicast_list) to make sure
something is really found. For example the device might be flushed and 
priv->multicast_list
become empty (emptying the multicast list does not wait for the query to 
finish).

> @@ -577,6 +585,9 @@ void ipoib_mcast_join_task(struct work_struct *work)
>                       break;
>               }
>  
> +             if (!list_is_last(&mcast->list, &priv->multicast_list))
> +                     list_move_tail(&mcast->list, &priv->multicast_list);
> +
>               ipoib_mcast_join(dev, mcast, 1);
>               return;
>       }

I don't think the list_is_last() check is really needed here.
And isn't priv->lock required for priv->multicast_list modifications?

--Yossi
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to