aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2008-04-17 00:09:35 -0400
committerRoland Dreier <rolandd@cisco.com>2008-04-17 00:09:35 -0400
commit9fdd5e5bf682130d1e1dd83d06e99eeafa645c0c (patch)
tree623f92fc4f16377a9a0f2a3e791bfc435897f4ea
parentd97c51707d7d0716881be84ffd2100449852e44b (diff)
IPoIB: Handle case when P_Key is deleted and re-added at same index
If a P_Key is deleted and then re-added at the same index, then IPoIB gets confused because __ipoib_ib_dev_flush() only checks whether the index is the same without checking whether the P_Key was present, so the interface is stopped when the P_Key is deleted, but the event when the P_Key is re-added gets ignored and the interface never gets restarted. Also, switch to using ib_find_pkey() instead of ib_find_cached_pkey() everywhere in IPoIB, since none of the places that look for P_Keys are in a fast path or in non-sleeping context, and in general we want to kill off the whole caching infrastructure eventually. This also fixes consistency problems caused because some IPoIB queries were cached and some were uncached during the window where the cache was not updated. Thanks to Venkata Subramonyam <vsubramo@cisco.com> for debugging this problem and testing this fix. Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c10
2 files changed, 7 insertions, 7 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 9d411f21460e..9db7b0bd9134 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -1007,9 +1007,9 @@ static int ipoib_cm_modify_tx_init(struct net_device *dev,
1007 struct ipoib_dev_priv *priv = netdev_priv(dev); 1007 struct ipoib_dev_priv *priv = netdev_priv(dev);
1008 struct ib_qp_attr qp_attr; 1008 struct ib_qp_attr qp_attr;
1009 int qp_attr_mask, ret; 1009 int qp_attr_mask, ret;
1010 ret = ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &qp_attr.pkey_index); 1010 ret = ib_find_pkey(priv->ca, priv->port, priv->pkey, &qp_attr.pkey_index);
1011 if (ret) { 1011 if (ret) {
1012 ipoib_warn(priv, "pkey 0x%x not in cache: %d\n", priv->pkey, ret); 1012 ipoib_warn(priv, "pkey 0x%x not found: %d\n", priv->pkey, ret);
1013 return ret; 1013 return ret;
1014 } 1014 }
1015 1015
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 8b4ff69ecb80..0205eb7c1bd3 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -594,7 +594,7 @@ static void ipoib_pkey_dev_check_presence(struct net_device *dev)
594 struct ipoib_dev_priv *priv = netdev_priv(dev); 594 struct ipoib_dev_priv *priv = netdev_priv(dev);
595 u16 pkey_index = 0; 595 u16 pkey_index = 0;
596 596
597 if (ib_find_cached_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) 597 if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index))
598 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 598 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
599 else 599 else
600 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 600 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
@@ -835,13 +835,13 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, int pkey_event)
835 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); 835 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
836 ipoib_ib_dev_down(dev, 0); 836 ipoib_ib_dev_down(dev, 0);
837 ipoib_ib_dev_stop(dev, 0); 837 ipoib_ib_dev_stop(dev, 0);
838 ipoib_pkey_dev_delay_open(dev); 838 if (ipoib_pkey_dev_delay_open(dev))
839 return; 839 return;
840 } 840 }
841 set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
842 841
843 /* restart QP only if P_Key index is changed */ 842 /* restart QP only if P_Key index is changed */
844 if (new_index == priv->pkey_index) { 843 if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) &&
844 new_index == priv->pkey_index) {
845 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); 845 ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n");
846 return; 846 return;
847 } 847 }