[ofa-general] RE: [PATCH] rdma_cm: create cm id even when port is down

Sean Hefty sean.hefty at intel.com
Fri Mar 27 14:36:56 PDT 2009


>  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 <yosefe at voltaire.com>
Acked-by: Sean Hefty <sean.hefty at intel.com>
>---

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;
> 	}




More information about the general mailing list