diff options
author | Eli Cohen <eli@mellanox.co.il> | 2008-07-15 02:48:50 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-07-15 02:48:50 -0400 |
commit | d0de13622d5ac658efe7c51521dbdbe0752aa3dd (patch) | |
tree | c61104a706ff1122b72888e0ed466d8183ee79e3 /drivers/infiniband | |
parent | 5892eff91ad60ba365ae7f75050ce464036c5396 (diff) |
IPoIB: Only set Q_Key once: after joining broadcast group
The current code will set the Q_Key for any join of a non-sendonly
multicast group. The operation involves a modify QP operation, which
is fairly heavyweight, and is only really required after the join of
the broadcast group. Fix this by adding a parameter to ipoib_mcast_attach()
to control when the Q_Key is set.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 28 |
3 files changed, 19 insertions, 15 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index b8753222c870..7b46e2d7b3c2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -485,7 +485,7 @@ void ipoib_path_iter_read(struct ipoib_path_iter *iter, | |||
485 | #endif | 485 | #endif |
486 | 486 | ||
487 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, | 487 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, |
488 | union ib_gid *mgid); | 488 | union ib_gid *mgid, int set_qkey); |
489 | int ipoib_mcast_detach(struct net_device *dev, u16 mlid, | 489 | int ipoib_mcast_detach(struct net_device *dev, u16 mlid, |
490 | union ib_gid *mgid); | 490 | union ib_gid *mgid); |
491 | 491 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 0b7d129161e1..55ebd950bf23 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -186,6 +186,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
186 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 186 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
187 | struct ipoib_ah *ah; | 187 | struct ipoib_ah *ah; |
188 | int ret; | 188 | int ret; |
189 | int set_qkey = 0; | ||
189 | 190 | ||
190 | mcast->mcmember = *mcmember; | 191 | mcast->mcmember = *mcmember; |
191 | 192 | ||
@@ -200,6 +201,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
200 | priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); | 201 | priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey); |
201 | spin_unlock_irq(&priv->lock); | 202 | spin_unlock_irq(&priv->lock); |
202 | priv->tx_wr.wr.ud.remote_qkey = priv->qkey; | 203 | priv->tx_wr.wr.ud.remote_qkey = priv->qkey; |
204 | set_qkey = 1; | ||
203 | } | 205 | } |
204 | 206 | ||
205 | if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { | 207 | if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) { |
@@ -212,7 +214,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast, | |||
212 | } | 214 | } |
213 | 215 | ||
214 | ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid), | 216 | ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid), |
215 | &mcast->mcmember.mgid); | 217 | &mcast->mcmember.mgid, set_qkey); |
216 | if (ret < 0) { | 218 | if (ret < 0) { |
217 | ipoib_warn(priv, "couldn't attach QP to multicast group " | 219 | ipoib_warn(priv, "couldn't attach QP to multicast group " |
218 | IPOIB_GID_FMT "\n", | 220 | IPOIB_GID_FMT "\n", |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index f50ebe0643ef..ba7c8868e6f7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c | |||
@@ -33,18 +33,13 @@ | |||
33 | 33 | ||
34 | #include "ipoib.h" | 34 | #include "ipoib.h" |
35 | 35 | ||
36 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) | 36 | int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid, int set_qkey) |
37 | { | 37 | { |
38 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 38 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
39 | struct ib_qp_attr *qp_attr; | 39 | struct ib_qp_attr *qp_attr = NULL; |
40 | int ret; | 40 | int ret; |
41 | u16 pkey_index; | 41 | u16 pkey_index; |
42 | 42 | ||
43 | ret = -ENOMEM; | ||
44 | qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); | ||
45 | if (!qp_attr) | ||
46 | goto out; | ||
47 | |||
48 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) { | 43 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) { |
49 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 44 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
50 | ret = -ENXIO; | 45 | ret = -ENXIO; |
@@ -52,12 +47,19 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) | |||
52 | } | 47 | } |
53 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 48 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
54 | 49 | ||
55 | /* set correct QKey for QP */ | 50 | if (set_qkey) { |
56 | qp_attr->qkey = priv->qkey; | 51 | ret = -ENOMEM; |
57 | ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY); | 52 | qp_attr = kmalloc(sizeof *qp_attr, GFP_KERNEL); |
58 | if (ret) { | 53 | if (!qp_attr) |
59 | ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret); | 54 | goto out; |
60 | goto out; | 55 | |
56 | /* set correct QKey for QP */ | ||
57 | qp_attr->qkey = priv->qkey; | ||
58 | ret = ib_modify_qp(priv->qp, qp_attr, IB_QP_QKEY); | ||
59 | if (ret) { | ||
60 | ipoib_warn(priv, "failed to modify QP, ret = %d\n", ret); | ||
61 | goto out; | ||
62 | } | ||
61 | } | 63 | } |
62 | 64 | ||
63 | /* attach QP to multicast group */ | 65 | /* attach QP to multicast group */ |