From patchwork Wed Jun 15 17:41:02 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hefty, Sean" X-Patchwork-Id: 882992 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p5FHf6f3004325 for ; Wed, 15 Jun 2011 17:41:06 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752494Ab1FORlF (ORCPT ); Wed, 15 Jun 2011 13:41:05 -0400 Received: from mga11.intel.com ([192.55.52.93]:25203 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752383Ab1FORlE convert rfc822-to-8bit (ORCPT ); Wed, 15 Jun 2011 13:41:04 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 15 Jun 2011 10:41:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.65,370,1304319600"; d="scan'208";a="16637932" Received: from orsmsx604.amr.corp.intel.com ([10.22.226.87]) by fmsmga002.fm.intel.com with ESMTP; 15 Jun 2011 10:41:04 -0700 Received: from orsmsx102.amr.corp.intel.com (10.22.225.129) by orsmsx604.amr.corp.intel.com (10.22.226.87) with Microsoft SMTP Server (TLS) id 8.2.255.0; Wed, 15 Jun 2011 10:41:04 -0700 Received: from orsmsx101.amr.corp.intel.com ([169.254.8.26]) by ORSMSX102.amr.corp.intel.com ([169.254.1.6]) with mapi id 14.01.0289.001; Wed, 15 Jun 2011 10:41:03 -0700 From: "Hefty, Sean" To: "linux-rdma (linux-rdma@vger.kernel.org)" Subject: [PATCH 3/8] librdmacm: Abstract ibverbs SRQ creation Thread-Topic: [PATCH 3/8] librdmacm: Abstract ibverbs SRQ creation Thread-Index: Acwrgsph2pat9EhGRYCpJQCC5TDG3A== Date: Wed, 15 Jun 2011 17:41:02 +0000 Message-ID: <1828884A29C6694DAF28B7E6B8A823730212DD@ORSMSX101.amr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.9.131.214] MIME-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 15 Jun 2011 17:41:06 +0000 (UTC) Support QPs with SRQs. If a user allocates an SRQ on an rdma_cm_id, we post receive messages directly to the SRQ. This also allows us to handle XRC SRQs, which may be associated with an rdma_cm_id, but without a corresponding QP. To handle registering memory, we store the PD associated with an rdma_cm_id directly with the id, rather than finding the PD using a QP pointer. Signed-off-by: Sean Hefty --- include/rdma/rdma_cma.h | 2 + include/rdma/rdma_verbs.h | 26 +++++++++++--- src/cma.c | 81 +++++++++++++++++++++++++++++++++++++-------- src/librdmacm.map | 2 + 4 files changed, 90 insertions(+), 21 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/rdma/rdma_cma.h b/include/rdma/rdma_cma.h index ab6016e..799a295 100755 --- a/include/rdma/rdma_cma.h +++ b/include/rdma/rdma_cma.h @@ -125,6 +125,8 @@ struct rdma_cm_id { struct ibv_cq *send_cq; struct ibv_comp_channel *recv_cq_channel; struct ibv_cq *recv_cq; + struct ibv_srq *srq; + struct ibv_pd *pd; }; enum { diff --git a/include/rdma/rdma_verbs.h b/include/rdma/rdma_verbs.h index e6a6b42..eca2c7a 100644 --- a/include/rdma/rdma_verbs.h +++ b/include/rdma/rdma_verbs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Intel Corporation. All rights reserved. + * Copyright (c) 2010-2011 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -52,26 +52,35 @@ static inline int rdma_seterrno(int ret) } /* + * Shared receive queues. + */ +int rdma_create_srq(struct rdma_cm_id *id, struct ibv_pd *pd, + struct ibv_srq_init_attr *attr); + +void rdma_destroy_srq(struct rdma_cm_id *id); + + +/* * Memory registration helpers. */ static inline struct ibv_mr * rdma_reg_msgs(struct rdma_cm_id *id, void *addr, size_t length) { - return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE); + return ibv_reg_mr(id->pd, addr, length, IBV_ACCESS_LOCAL_WRITE); } static inline struct ibv_mr * rdma_reg_read(struct rdma_cm_id *id, void *addr, size_t length) { - return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE | - IBV_ACCESS_REMOTE_READ); + return ibv_reg_mr(id->pd, addr, length, IBV_ACCESS_LOCAL_WRITE | + IBV_ACCESS_REMOTE_READ); } static inline struct ibv_mr * rdma_reg_write(struct rdma_cm_id *id, void *addr, size_t length) { - return ibv_reg_mr(id->qp->pd, addr, length, IBV_ACCESS_LOCAL_WRITE | - IBV_ACCESS_REMOTE_WRITE); + return ibv_reg_mr(id->pd, addr, length, IBV_ACCESS_LOCAL_WRITE | + IBV_ACCESS_REMOTE_WRITE); } static inline int @@ -96,7 +105,10 @@ rdma_post_recvv(struct rdma_cm_id *id, void *context, struct ibv_sge *sgl, wr.sg_list = sgl; wr.num_sge = nsge; - return rdma_seterrno(ibv_post_recv(id->qp, &wr, &bad)); + if (id->srq) + return rdma_seterrno(ibv_post_srq_recv(id->srq, &wr, &bad)); + else + return rdma_seterrno(ibv_post_recv(id->qp, &wr, &bad)); } static inline int diff --git a/src/cma.c b/src/cma.c index d6cb626..e5ea7db 100755 --- a/src/cma.c +++ b/src/cma.c @@ -116,7 +116,6 @@ struct cma_id_private { pthread_mutex_t mut; uint32_t handle; struct cma_multicast *mc_list; - struct ibv_pd *pd; struct ibv_qp_init_attr *qp_init_attr; uint8_t initiator_depth; uint8_t responder_resources; @@ -387,6 +386,7 @@ static int ucma_get_device(struct cma_id_private *id_priv, uint64_t guid) if (cma_dev->guid == guid) { id_priv->cma_dev = cma_dev; id_priv->id.verbs = cma_dev->verbs; + id_priv->id.pd = cma_dev->pd; return 0; } } @@ -1141,32 +1141,28 @@ static void ucma_destroy_cqs(struct rdma_cm_id *id) ibv_destroy_comp_channel(id->send_cq_channel); } -static int ucma_create_cqs(struct rdma_cm_id *id, struct ibv_qp_init_attr *attr) +static int ucma_create_cqs(struct rdma_cm_id *id, uint32_t send_size, uint32_t recv_size) { - if (!attr->recv_cq) { + if (recv_size) { id->recv_cq_channel = ibv_create_comp_channel(id->verbs); if (!id->recv_cq_channel) goto err; - id->recv_cq = ibv_create_cq(id->verbs, attr->cap.max_recv_wr, + id->recv_cq = ibv_create_cq(id->verbs, recv_size, id, id->recv_cq_channel, 0); if (!id->recv_cq) goto err; - - attr->recv_cq = id->recv_cq; } - if (!attr->send_cq) { + if (send_size) { id->send_cq_channel = ibv_create_comp_channel(id->verbs); if (!id->send_cq_channel) goto err; - id->send_cq = ibv_create_cq(id->verbs, attr->cap.max_send_wr, + id->send_cq = ibv_create_cq(id->verbs, send_size, id, id->send_cq_channel, 0); if (!id->send_cq) goto err; - - attr->send_cq = id->send_cq; } return 0; @@ -1175,6 +1171,53 @@ err: return ERR(ENOMEM); } +int rdma_create_srq(struct rdma_cm_id *id, struct ibv_pd *pd, + struct ibv_srq_init_attr *attr) +{ + struct cma_id_private *id_priv; + struct ibv_srq *srq; + int ret; + + id_priv = container_of(id, struct cma_id_private, id); + if (!pd) + pd = id->pd; + +#ifdef IBV_XRC_OPS + if (attr->srq_type == IBV_SRQT_XRC) { + if (!attr->ext.xrc.cq) { + ret = ucma_create_cqs(id, 0, attr->attr.max_wr); + if (ret) + return ret; + + attr->ext.xrc.cq = id->recv_cq; + } + } + + srq = ibv_create_xsrq(pd, attr); +#else + srq = ibv_create_srq(pd, attr); +#endif + if (!srq) { + ret = -1; + goto err; + } + + id->pd = pd; + id->srq = srq; + return 0; +err: + ucma_destroy_cqs(id); + return ret; +} + +void rdma_destroy_srq(struct rdma_cm_id *id) +{ + ibv_destroy_srq(id->srq); + if (!id->qp) + ucma_destroy_cqs(id); + id->srq = NULL; +} + int rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd, struct ibv_qp_init_attr *qp_init_attr) { @@ -1187,14 +1230,19 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd, id_priv = container_of(id, struct cma_id_private, id); if (!pd) - pd = id_priv->cma_dev->pd; + pd = id->pd; else if (id->verbs != pd->context) return ERR(EINVAL); - ret = ucma_create_cqs(id, qp_init_attr); + ret = ucma_create_cqs(id, qp_init_attr->send_cq ? 0 : qp_init_attr->cap.max_send_wr, + qp_init_attr->recv_cq ? 0 : qp_init_attr->cap.max_recv_wr); if (ret) return ret; + if (!qp_init_attr->send_cq) + qp_init_attr->send_cq = id->send_cq; + if (!qp_init_attr->recv_cq) + qp_init_attr->recv_cq = id->recv_cq; qp = ibv_create_qp(pd, qp_init_attr); if (!qp) { ret = ERR(ENOMEM); @@ -1208,6 +1256,7 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd, if (ret) goto err2; + id->pd = pd; id->qp = qp; return 0; err2: @@ -1380,7 +1429,7 @@ int rdma_get_request(struct rdma_cm_id *listen, struct rdma_cm_id **id) struct ibv_qp_init_attr attr; attr = *id_priv->qp_init_attr; - ret = rdma_create_qp(event->id, id_priv->pd, &attr); + ret = rdma_create_qp(event->id, listen->pd, &attr); if (ret) goto err; } @@ -2107,7 +2156,8 @@ static int ucma_passive_ep(struct rdma_cm_id *id, struct rdma_addrinfo *res, return ret; id_priv = container_of(id, struct cma_id_private, id); - id_priv->pd = pd; + if (pd) + id->pd = pd; if (qp_init_attr) { id_priv->qp_init_attr = malloc(sizeof *qp_init_attr); @@ -2192,6 +2242,9 @@ void rdma_destroy_ep(struct rdma_cm_id *id) if (id->qp) rdma_destroy_qp(id); + if (id->srq) + rdma_destroy_srq(id); + id_priv = container_of(id, struct cma_id_private, id); if (id_priv->qp_init_attr) free(id_priv->qp_init_attr); diff --git a/src/librdmacm.map b/src/librdmacm.map index 19b193a..b3235ff 100644 --- a/src/librdmacm.map +++ b/src/librdmacm.map @@ -33,5 +33,7 @@ RDMACM_1.0 { rdma_get_request; rdma_create_ep; rdma_destroy_ep; + rdma_create_srq; + rdma_destroy_srq; local: *; };