Hello, Here is a new version of the patch. Major points of change: 1. Delays interface initialization until port is Active. 2. Uses pkey-table first entry for main interface. 3. Keeps old algorithm for sub-interface (keeps manually assigned p_key and adjusts UD QP p_key index if sub-interface reinitialized).
Please review. Signed-off-by: Alex Estrin <[email protected]> --- diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 784c291..cd5639c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -51,6 +51,7 @@ MODULE_PARM_DESC(data_debug_level, #endif static DEFINE_MUTEX(pkey_mutex); +static void ipoib_pkey_dev_check_presence(struct net_device *dev); struct ipoib_ah *ipoib_create_ah(struct net_device *dev, struct ib_pd *pd, struct ib_ah_attr *attr) @@ -676,12 +677,13 @@ int ipoib_ib_dev_open(struct net_device *dev) struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; - if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &priv->pkey_index)) { + ipoib_pkey_dev_check_presence(dev); + + if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { ipoib_warn(priv, "P_Key 0x%04x not found\n", priv->pkey); clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); return -1; } - set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); ret = ipoib_init_qp(dev); if (ret) { @@ -719,9 +721,26 @@ 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); - u16 pkey_index = 0; + struct ib_port_attr port_attr; + + 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)) + if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &priv->pkey_index)) clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); else set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); @@ -972,7 +991,8 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, } /* restart QP only if P_Key index is changed */ - if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && + if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags) && + test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && new_index == priv->pkey_index) { ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); return; 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;
ipoib_pkey_bootup_race_v2.patch
Description: ipoib_pkey_bootup_race_v2.patch
_______________________________________________ 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
