[ofw] [PATCH 9/11] librdmacm: add rdma_create_ep and rdma_destroy_ep

Hefty, Sean sean.hefty at intel.com
Mon Aug 16 16:23:17 PDT 2010


Add calls to create rdma_cm_id's using the output of rdma_getaddrinfo
as the input to the calls.  This simplifies the connection establishment
process.  rdam_create_ep performs the equivalent to rdam_create_id,
rdma_resolve_addr, rdma_resolve_route, and rdma_create_qp.

From: Sean Hefty <sean.hefty at intel.com>
---
 trunk/ulp/librdmacm/include/rdma/rdma_cma.h |   39 ++++++++++++
 trunk/ulp/librdmacm/src/cma.cpp             |   88 +++++++++++++++++++++++++++
 2 files changed, 127 insertions(+), 0 deletions(-)

diff --git a/trunk/ulp/librdmacm/include/rdma/rdma_cma.h b/trunk/ulp/librdmacm/include/rdma/rdma_cma.h
index 489fa66..bec57f0 100644
--- a/trunk/ulp/librdmacm/include/rdma/rdma_cma.h
+++ b/trunk/ulp/librdmacm/include/rdma/rdma_cma.h
@@ -265,6 +265,45 @@ int rdma_create_id(struct rdma_event_channel *channel,
 				   enum rdma_port_space ps);
 
 /**
+ * rdma_create_ep - Allocate a communication identifier and qp.
+ * @id: A reference where the allocated communication identifier will be
+ *   returned.
+ * @res: Result from rdma_getaddrinfo, which specifies the source and
+ *   destination addresses, plus optional routing and connection information.
+ * @pd: Optional protection domain.  This parameter is ignored if qp_init_attr
+ *   is NULL.
+ * @qp_init_attr: Optional attributes for a QP created on the rdma_cm_id.
+ * Description:
+ *   Create an identifier and option QP used for communication.
+ * Notes:
+ *   If qp_init_attr is provided, then a queue pair will be allocated and
+ *   associated with the rdma_cm_id.  If a pd is provided, the QP will be
+ *   created on that PD.  Otherwise, the QP will be allocated on a default
+ *   PD.
+ *   The rdma_cm_id will be set to use synchronous operations (connect,
+ *   listen, and get_request).  To convert to asynchronous operation, the
+ *   rdma_cm_id should be migrated to a user allocated event channel.
+ * See also:
+ *   rdma_create_id, rdma_create_qp, rdma_migrate_id, rdma_connect,
+ *   rdma_listen
+ */
+__declspec(dllexport)
+int rdma_create_ep(struct rdma_cm_id **id, struct rdma_addrinfo *res,
+		   struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr);
+
+/**
+ * rdma_destroy_ep - Deallocates a communication identifier and qp.
+ * @id: The communication identifer to destroy.
+ * Description:
+ *   Destroys the specified rdma_cm_id and any associated QP created
+ *   on that id.
+ * See also:
+ *   rdma_create_ep
+ */
+__declspec(dllexport)
+void rdma_destroy_ep(struct rdma_cm_id *id);
+
+/**
  * rdma_destroy_id - Release a communication identifier.
  * @id: The communication identifier to destroy.
  * Description:
diff --git a/trunk/ulp/librdmacm/src/cma.cpp b/trunk/ulp/librdmacm/src/cma.cpp
index f897245..835d020 100644
--- a/trunk/ulp/librdmacm/src/cma.cpp
+++ b/trunk/ulp/librdmacm/src/cma.cpp
@@ -74,6 +74,8 @@ struct cma_id_private
 	int							index;
 	volatile LONG				refcnt;
 	struct rdma_cm_id			**req_list;
+	struct ibv_pd				*pd;
+	struct ibv_qp_init_attr		*qp_init_attr;
 	uint8_t						initiator_depth;
 	uint8_t						responder_resources;
 };
@@ -949,6 +951,12 @@ int rdma_get_request(struct rdma_cm_id *listen, struct rdma_cm_id **id)
 		goto err;
 	}
 
+	if (id_priv->qp_init_attr) {
+		ret = rdma_create_qp(event->id, id_priv->pd, id_priv->qp_init_attr);
+		if (ret)
+			goto err;
+	}
+
 	*id = event->id;
 	(*id)->event = event;
 	return 0;
@@ -1344,6 +1352,86 @@ int rdma_migrate_id(struct rdma_cm_id *id, struct rdma_event_channel *channel)
 	return 0;
 }
 
+static int ucma_passive_ep(struct rdma_cm_id *id, struct rdma_addrinfo *res,
+						   struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr)
+{
+	struct cma_id_private *id_priv;
+	int ret;
+
+	ret = rdma_bind_addr(id, res->ai_src_addr);
+	if (ret)
+		return ret;
+
+	id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);
+	id_priv->pd = pd;
+
+	if (qp_init_attr) {
+		id_priv->qp_init_attr = new struct ibv_qp_init_attr;
+		if (!id_priv->qp_init_attr)
+			return rdma_seterrno(ENOMEM);
+
+		*id_priv->qp_init_attr = *qp_init_attr;
+		id_priv->qp_init_attr->qp_type = (enum ibv_qp_type) res->ai_qp_type;
+	}
+
+	return 0;
+}
+
+__declspec(dllexport)
+int rdma_create_ep(struct rdma_cm_id **id, struct rdma_addrinfo *res,
+				   struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr)
+{
+	struct rdma_cm_id *cm_id;
+	int ret;
+
+	ret = rdma_create_id(NULL, &cm_id, NULL, (enum rdma_port_space) res->ai_port_space);
+	if (ret)
+		return ret;
+
+	if (res->ai_flags & RAI_PASSIVE) {
+		ret = ucma_passive_ep(cm_id, res, pd, qp_init_attr);
+		if (ret)
+			goto err;
+		goto out;
+	}
+
+	ret = rdma_resolve_addr(cm_id, res->ai_src_addr, res->ai_dst_addr, 2000);
+	if (ret)
+		goto err;
+
+	ret = rdma_resolve_route(cm_id, 2000);
+	if (ret)
+		goto err;
+
+	qp_init_attr->qp_type = (enum ibv_qp_type) res->ai_qp_type;
+	ret = rdma_create_qp(cm_id, pd, qp_init_attr);
+	if (ret)
+		goto err;
+
+out:
+	*id = cm_id;
+	return 0;
+
+err:
+	rdma_destroy_ep(cm_id);
+	return ret;
+}
+
+__declspec(dllexport)
+void rdma_destroy_ep(struct rdma_cm_id *id)
+{
+	struct cma_id_private *id_priv;
+
+	if (id->qp)
+		rdma_destroy_qp(id);
+
+	id_priv = CONTAINING_RECORD(id, struct cma_id_private, id);
+	if (id_priv->qp_init_attr) {
+		delete id_priv->qp_init_attr;
+	}
+	rdma_destroy_id(id);
+}
+
 __declspec(dllexport)
 int rdmaw_wsa_errno(int wsa_err)
 {




More information about the ofw mailing list