[ofa-general] [PATCH] ipoib: failure during startup wiith non-default pkey set.

Alex Estrin alex.estrin at qlogic.com
Fri Jan 2 08:39:47 PST 2009


It seems this patch was missed. Reposting.

Ipoib uses the first pkey in the pkey table for its ib0 interface.
Race is possible during bootup, when ipoib starts before the port is Active and has a
default pkey table with 0xffff as the only pkey. SM can program the pkey table differently
when moves port to Active, but at this point ipoib already started using default pkey.
However there is no race, if ipoib started after the port is Active, 
then ipoib will find the first pkey as the SM programmed it.

Proposed patch will delay ib0 interface initialization until port moved to Active state.
After port is Active, interface will pickup correct pkey, then adjust broadcast gid before it joined broadcast group.
Please note, the patch is not intended to touch sub-interfaces with locally programmed pkeys.


Signed-off-by: Alex Estrin <alex.estrin at qlogic.com>

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 784c291..459e2b9 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -719,7 +719,25 @@ int ipoib_ib_dev_open(struct net_device *dev)
 static void ipoib_pkey_dev_check_presence(struct net_device *dev)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+	struct ib_port_attr    port_attr;
 	u16 pkey_index = 0;
+	
+	if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
+		
+		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+		if (ib_query_port(priv->ca, priv->port, &port_attr)) {
+			ipoib_warn(priv, "Query port attrs failed\n");
+			return;
+		}
+		if (port_attr.state != IB_PORT_ACTIVE) {
+			return;
+		} 
+		if (ib_query_pkey(priv->ca, priv->port, 0, &priv->pkey)) {
+			ipoib_warn(priv, "Query P_Key table entry 0 failed\n");
+			return;
+		}
+		set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
+	}
 
 	if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))
 		clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 016a057..4d270e2 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -556,6 +556,13 @@ void ipoib_mcast_join_task(struct work_struct *work)
 		}
 
 		spin_lock_irq(&priv->lock);
+
+		if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
+			/* fix broadcast gid in case if pkey was changed */
+			priv->pkey |= 0x8000;
+			priv->dev->broadcast[8] = priv->pkey >> 8;
+			priv->dev->broadcast[9] = priv->pkey & 0xff;
+		}
 		memcpy(broadcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
 		       sizeof (union ib_gid));
 		priv->broadcast = broadcast;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: ipoib_pkey_bootup_race.patch
Type: application/octet-stream
Size: 1805 bytes
Desc: ipoib_pkey_bootup_race.patch
URL: <http://lists.openfabrics.org/pipermail/general/attachments/20090102/358ab2fb/attachment.obj>


More information about the general mailing list