Because ipoib_workqueue is not flushed when ipoib interface is brought down, ipoib_mcast_join() may trigger a join to the broadcast group after priv->broadcast was set to NULL (during cleanup). This will cause ipoib to be joined to the broadcast group when interface is down. As a side effect, this breaks the optimization of setting qkey only when joining the broadcast group.
Signed-off-by: Yossi Etigin <[email protected]> -- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) Index: b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c =================================================================== --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2008-11-19 21:33:54.000000000 +0200 +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2008-11-26 18:08:48.000000000 +0200 @@ -497,7 +497,7 @@ static void ipoib_mcast_join(struct net_ IB_SA_MCMEMBER_REC_PKEY | IB_SA_MCMEMBER_REC_JOIN_STATE; - if (create) { + if (create && priv->broadcast) { comp_mask |= IB_SA_MCMEMBER_REC_QKEY | IB_SA_MCMEMBER_REC_MTU_SELECTOR | @@ -565,7 +565,8 @@ void ipoib_mcast_join_task(struct work_s ipoib_warn(priv, "ib_query_port failed\n"); } - if (!priv->broadcast) { + rtnl_lock(); + if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags) && !priv->broadcast) { struct ipoib_mcast *broadcast; broadcast = ipoib_mcast_alloc(dev, 1); @@ -576,6 +577,7 @@ void ipoib_mcast_join_task(struct work_s queue_delayed_work(ipoib_workqueue, &priv->mcast_join_task, HZ); mutex_unlock(&mcast_mutex); + rtnl_unlock(); return; } @@ -587,8 +589,10 @@ void ipoib_mcast_join_task(struct work_s __ipoib_mcast_add(dev, priv->broadcast); spin_unlock_irq(&priv->lock); } + rtnl_unlock(); - if (!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { + if (priv->broadcast && + !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { if (!test_bit(IPOIB_MCAST_FLAG_BUSY, &priv->broadcast->flags)) ipoib_mcast_join(dev, priv->broadcast, 0); return; @@ -617,7 +621,8 @@ void ipoib_mcast_join_task(struct work_s return; } - priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu)); + if (priv->broadcast) + priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu)); if (!ipoib_cm_admin_enabled(dev)) { rtnl_lock(); _______________________________________________ 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
