>  When doing rdma_resolve_addr() and relevant port is down, the function fails
>and rdma_cm id is not bound to the device. Therefore, application does not have
>device handle and cannot wait for the port to become active. The function
>fails because ipoib is not joined to the multicast group and therefore sa does
>not have a multicast record to take a qkey from.
>  The patch here is to make lazy qkey resolution - cma_set_qkey will set
>id_priv->qkey if it was not set, and will be called just before the qkey is
>really required.
>
>Signed-off-by: Yossi Etigin <[email protected]>
Acked-by: Sean Hefty <[email protected]>
>---

Roland, a thread that discussed this starts here:

http://lists.openfabrics.org/pipermail/general/2009-February/056895.html

The subject never contained '[PATCH]', so it was probably missed, but Yossi's
patch should be good for 2.6.30.

> drivers/infiniband/core/cma.c |   41 +++++++++++++++++++++++++++--------------
> 1 file changed, 27 insertions(+), 14 deletions(-)
>
>Index: b/drivers/infiniband/core/cma.c
>===================================================================
>--- a/drivers/infiniband/core/cma.c    2009-03-10 18:21:47.000000000 +0200
>+++ b/drivers/infiniband/core/cma.c    2009-03-10 19:22:18.000000000 +0200
>@@ -297,21 +297,25 @@ static void cma_detach_from_dev(struct r
>       id_priv->cma_dev = NULL;
> }
>
>-static int cma_set_qkey(struct ib_device *device, u8 port_num,
>-                      enum rdma_port_space ps,
>-                      struct rdma_dev_addr *dev_addr, u32 *qkey)
>+static int cma_set_qkey(struct rdma_id_private *id_priv)
> {
>       struct ib_sa_mcmember_rec rec;
>       int ret = 0;
>
>-      switch (ps) {
>+      if (id_priv->qkey)
>+              return;
>+
>+      switch (id_priv->id.ps) {
>       case RDMA_PS_UDP:
>-              *qkey = RDMA_UDP_QKEY;
>+              id_priv->qkey = RDMA_UDP_QKEY;
>               break;
>       case RDMA_PS_IPOIB:
>-              ib_addr_get_mgid(dev_addr, &rec.mgid);
>-              ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec);
>-              *qkey = be32_to_cpu(rec.qkey);
>+              ib_addr_get_mgid(&id_priv->id.route.addr.dev_addr, &rec.mgid);
>+              ret = ib_sa_get_mcmember_rec(id_priv->id.device,
>+                                           id_priv->id.port_num, &rec.mgid,
>+                                           &rec);
>+              if (!ret)
>+                      id_priv->qkey = be32_to_cpu(rec.qkey);
>               break;
>       default:
>               break;
>@@ -341,12 +345,7 @@ static int cma_acquire_dev(struct rdma_i
>               ret = ib_find_cached_gid(cma_dev->device, &gid,
>                                        &id_priv->id.port_num, NULL);
>               if (!ret) {
>-                      ret = cma_set_qkey(cma_dev->device,
>-                                         id_priv->id.port_num,
>-                                         id_priv->id.ps, dev_addr,
>-                                         &id_priv->qkey);
>-                      if (!ret)
>-                              cma_attach_to_dev(id_priv, cma_dev);
>+                      cma_attach_to_dev(id_priv, cma_dev);
>                       break;
>               }
>       }
>@@ -578,6 +577,10 @@ static int cma_ib_init_qp_attr(struct rd
>       *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
>
>       if (cma_is_ud_ps(id_priv->id.ps)) {
>+              ret = cma_set_qkey(id_priv);
>+              if (ret)
>+                      return ret;
>+
>               qp_attr->qkey = id_priv->qkey;
>               *qp_attr_mask |= IB_QP_QKEY;
>       } else {
>@@ -2201,6 +2204,12 @@ static int cma_sidr_rep_handler(struct i
>                       event.status = ib_event->param.sidr_rep_rcvd.status;
>                       break;
>               }
>+              ret = cma_set_qkey(id_priv);
>+              if (ret) {
>+                      event.event = RDMA_CM_EVENT_ADDR_ERROR;
>+                      event.status = -EINVAL;
>+                      break;
>+              }
>               if (id_priv->qkey != rep->qkey) {
>                       event.event = RDMA_CM_EVENT_UNREACHABLE;
>                       event.status = -EINVAL;
>@@ -2480,10 +2489,14 @@ static int cma_send_sidr_rep(struct rdma
>                            const void *private_data, int private_data_len)
> {
>       struct ib_cm_sidr_rep_param rep;
>+      int ret;
>
>       memset(&rep, 0, sizeof rep);
>       rep.status = status;
>       if (status == IB_SIDR_SUCCESS) {
>+              ret = cma_set_qkey(id_priv);
>+              if (ret)
>+                      return ret;
>               rep.qp_num = id_priv->qp_num;
>               rep.qkey = id_priv->qkey;
>       }

_______________________________________________
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

Reply via email to