[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