[ofa-general] [PATCH] IB/IPoIB: Don't let a bad muticast address in the join list stop subsequent joins
Yossi Etigin
yosefe at voltaire.com
Mon Jul 6 12:54:33 PDT 2009
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
More information about the general
mailing list