From patchwork Fri Sep 2 00:09:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Knut Omang X-Patchwork-Id: 9310181 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 73779607D6 for ; Fri, 2 Sep 2016 00:10:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 516C529564 for ; Fri, 2 Sep 2016 00:10:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 463A42959E; Fri, 2 Sep 2016 00:10:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B2F5E29564 for ; Fri, 2 Sep 2016 00:10:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751711AbcIBAKS (ORCPT ); Thu, 1 Sep 2016 20:10:18 -0400 Received: from userp1040.oracle.com ([156.151.31.81]:21156 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751957AbcIBAKR (ORCPT ); Thu, 1 Sep 2016 20:10:17 -0400 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u820AFEV023134 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 2 Sep 2016 00:10:15 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u820AFsK002407 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 2 Sep 2016 00:10:15 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u820AEQa003760; Fri, 2 Sep 2016 00:10:15 GMT Received: from abi.no.oracle.com (/10.172.144.123) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 01 Sep 2016 17:10:14 -0700 From: Knut Omang To: Doug Ledford Cc: linux-rdma@vger.kernel.org, Knut Omang Subject: [PATCH 8/9] ib_uverbs: Support for kernel implementation of XRC Date: Fri, 2 Sep 2016 02:09:28 +0200 Message-Id: <1472774969-18997-9-git-send-email-knut.omang@oracle.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1472774969-18997-1-git-send-email-knut.omang@oracle.com> References: <1472774969-18997-1-git-send-email-knut.omang@oracle.com> X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Extends the kernel/user space interface for work requests to also provide the XRC shared receive queue number. Necessary to support kernel level implementation of user verbs for XRC. Requires a corresponding libibverbs change to support XRC. Also fix kernel support for XRC broken by commit "IB: remove xrc_remote_srq_num from struct ib_send_wr" which removed a field needed to support kernel side XRC as part of an effort to trim a work request to sizes dependent of the actual request instead of the union approach. With this commit I try to follow the pattern outlined by that cleanup to also support kernel side XRC. Since XRC attributes are associated with QP type and are (almost) orthogonal to the type of request, the XRC specific attribute(s) would have to be applicable to several different work request type specific subtypes. Since the subtypes have different sizes, putting the xrc specific attributes at the end would require accessor functions and to keep explicit track of the size of the subtype used. The chosen solution is to introduce the xrc specific attributes at the top of the struct instead, this way type checking is taking care of most issues, except that extra care is needed at deallocation time. Note that this requires padding of the xrc specific attributes that matches the size of struct ib_sge, to avoid that the ALIGN() calls used to ensure that the scatter list of the work is aligned does not extend beyond the size of the allocates space: struct ib_xrc_wr { ; struct ib_send_wr wr; } < subtype extensions will still extend ib_send_wr down here > Signed-off-by: Knut Omang --- drivers/infiniband/core/uverbs_cmd.c | 40 ++++++++++++++++++++++++++++-------- include/rdma/ib_verbs.h | 12 +++++++++++ include/uapi/rdma/ib_user_verbs.h | 2 ++ 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 4323093..f7e9904 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -2469,12 +2469,30 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, return in_len; } -static void *alloc_wr(size_t wr_size, __u32 num_sge) +static void *alloc_wr(struct ib_qp *qp, size_t wr_size, __u32 num_sge) { - return kmalloc(ALIGN(wr_size, sizeof (struct ib_sge)) + - num_sge * sizeof (struct ib_sge), GFP_KERNEL); + void *wr; + size_t xrc_ext = qp->qp_type == IB_QPT_XRC_INI ? + sizeof(struct ib_xrc_wr) - sizeof(struct ib_send_wr) : + 0; + + wr = kmalloc(ALIGN(wr_size + xrc_ext, sizeof (struct ib_sge)) + + num_sge * sizeof (struct ib_sge), GFP_KERNEL); + if (unlikely(!wr)) + return wr; + + return wr + xrc_ext; }; +static void free_wr(struct ib_qp *qp, struct ib_send_wr *wr) +{ + void *d; + if (unlikely(!wr)) + return; + d = qp->qp_type == IB_QPT_XRC_INI ? xrc_wr(wr) : (void *)wr; + kfree(d); +} + ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, struct ib_device *ib_dev, const char __user *buf, int in_len, @@ -2509,6 +2527,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, goto out; is_ud = qp->qp_type == IB_QPT_UD; + sg_ind = 0; last = NULL; for (i = 0; i < cmd.wr_count; ++i) { @@ -2534,7 +2553,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, } next_size = sizeof(*ud); - ud = alloc_wr(next_size, user_wr->num_sge); + ud = alloc_wr(qp, next_size, user_wr->num_sge); if (!ud) { ret = -ENOMEM; goto out_put; @@ -2556,7 +2575,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, struct ib_rdma_wr *rdma; next_size = sizeof(*rdma); - rdma = alloc_wr(next_size, user_wr->num_sge); + rdma = alloc_wr(qp, next_size, user_wr->num_sge); if (!rdma) { ret = -ENOMEM; goto out_put; @@ -2571,7 +2590,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, struct ib_atomic_wr *atomic; next_size = sizeof(*atomic); - atomic = alloc_wr(next_size, user_wr->num_sge); + atomic = alloc_wr(qp, next_size, user_wr->num_sge); if (!atomic) { ret = -ENOMEM; goto out_put; @@ -2587,7 +2606,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, user_wr->opcode == IB_WR_SEND_WITH_IMM || user_wr->opcode == IB_WR_SEND_WITH_INV) { next_size = sizeof(*next); - next = alloc_wr(next_size, user_wr->num_sge); + next = alloc_wr(qp, next_size, user_wr->num_sge); if (!next) { ret = -ENOMEM; goto out_put; @@ -2605,6 +2624,11 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, next->ex.invalidate_rkey = user_wr->ex.invalidate_rkey; } + if (qp->qp_type == IB_QPT_XRC_INI) { + struct ib_xrc_wr *xrc = xrc_wr(next); + xrc->remote_srqn = user_wr->xrc_remote_srq_num; + } + if (!last) wr = next; else @@ -2653,7 +2677,7 @@ out_put: if (is_ud && ud_wr(wr)->ah) put_ah_read(ud_wr(wr)->ah); next = wr->next; - kfree(wr); + free_wr(qp, wr); wr = next; } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 192d591..093d68e 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1276,6 +1276,18 @@ static inline struct ib_sig_handover_wr *sig_handover_wr(struct ib_send_wr *wr) return container_of(wr, struct ib_sig_handover_wr, wr); } +struct ib_xrc_wr { + u32 remote_srqn; + u32 reserved1; + u64 reserved2; + struct ib_send_wr wr; +}; + +static inline struct ib_xrc_wr *xrc_wr(struct ib_send_wr *wr) +{ + return container_of(wr, struct ib_xrc_wr, wr); +} + struct ib_recv_wr { struct ib_recv_wr *next; union { diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index 6b8c9c0..db74a5e 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h @@ -725,6 +725,8 @@ struct ib_uverbs_send_wr { __u32 reserved; } ud; } wr; + __u32 xrc_remote_srq_num; + __u32 reserved; }; struct ib_uverbs_post_send {