[openib-general] Re: ipoib_multicast_ah.patch

Roland Dreier rdreier at cisco.com
Mon Feb 27 20:44:57 PST 2006


    Michael> I guess there's a misunderstanding here. Its pretty
    Michael> simple: ipoib_mcast_send tests mcast->ah twice under
    Michael> priv->lock.  ipoib_mcast_join_finish modifies the
    Michael> mcast->ah without taking a lock.  No *other* place
    Michael> modifies the mcast->ah.

    Michael> As a solution, take priv->lock around assignment to
    Michael> mcast->ah thus making sure ipoib_mcast_send is not in
    Michael> flight.

Ah, I got it now.  But since ipoib_mcast_join_finish is always called with
interrupts enabled, we can use the following slightly simpler version.

I applied this and queued it for 2.6.17 (I don't think this is
critical enough for 2.6.16 at this stage).

 - R.

--- infiniband/ulp/ipoib/ipoib_multicast.c	(revision 5514)
+++ infiniband/ulp/ipoib/ipoib_multicast.c	(working copy)
@@ -213,6 +213,7 @@ static int ipoib_mcast_join_finish(struc
 {
 	struct net_device *dev = mcast->dev;
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ipoib_ah *ah;
 	int ret;
 
 	mcast->mcmember = *mcmember;
@@ -269,8 +270,8 @@ static int ipoib_mcast_join_finish(struc
 				av.static_rate, priv->local_rate,
 				ib_sa_rate_enum_to_int(mcast->mcmember.rate));
 
-		mcast->ah = ipoib_create_ah(dev, priv->pd, &av);
-		if (!mcast->ah) {
+		ah = ipoib_create_ah(dev, priv->pd, &av);
+		if (!ah) {
 			ipoib_warn(priv, "ib_address_create failed\n");
 		} else {
 			ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
@@ -280,6 +281,10 @@ static int ipoib_mcast_join_finish(struc
 					be16_to_cpu(mcast->mcmember.mlid),
 					mcast->mcmember.sl);
 		}
+
+		spin_lock_irq(&priv->lock);
+		mcast->ah = ah;
+		spin_unlock_irq(&priv->lock);
 	}
 
 	/* actually send any queued packets */



More information about the general mailing list