From patchwork Thu Feb 4 21:52:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Wise X-Patchwork-Id: 8239811 Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CFBD79F4DD for ; Fri, 5 Feb 2016 21:48:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B282C20125 for ; Fri, 5 Feb 2016 21:48:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8CCF120142 for ; Fri, 5 Feb 2016 21:48:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750866AbcBEVsk (ORCPT ); Fri, 5 Feb 2016 16:48:40 -0500 Received: from smtp.opengridcomputing.com ([72.48.136.20]:58483 "EHLO smtp.opengridcomputing.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750844AbcBEVsj (ORCPT ); Fri, 5 Feb 2016 16:48:39 -0500 Received: from smtp.ogc.us (build2.ogc.int [10.10.0.32]) by smtp.opengridcomputing.com (Postfix) with ESMTP id 5374C29E5F for ; Fri, 5 Feb 2016 15:48:39 -0600 (CST) Received: by smtp.ogc.us (Postfix, from userid 503) id 417A5E0753; Fri, 5 Feb 2016 15:48:39 -0600 (CST) Message-Id: In-Reply-To: References: From: Steve Wise Date: Thu, 4 Feb 2016 13:52:40 -0800 Subject: [PATCH 4/6] IB: add a simple MR pool To: linux-rdma@vger.kernel.org Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-6.2 required=5.0 tests=BAYES_00, DATE_IN_PAST_12_24, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Christoph Hellwig Signed-off-by: Christoph Hellwig Signed-off-by: Steve Wise --- drivers/infiniband/core/Makefile | 2 +- drivers/infiniband/core/mr_pool.c | 85 +++++++++++++++++++++++++++++++++++++++ drivers/infiniband/core/verbs.c | 4 ++ include/rdma/ib_verbs.h | 10 ++++- include/rdma/mr_pool.h | 20 +++++++++ 5 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 drivers/infiniband/core/mr_pool.c create mode 100644 include/rdma/mr_pool.h diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index f818538..48bd9d8 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \ ib_core-y := packer.o ud_header.o verbs.o cq.o sysfs.o \ device.o fmr_pool.o cache.o netlink.o \ - roce_gid_mgmt.o + roce_gid_mgmt.o mr_pool.o ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o diff --git a/drivers/infiniband/core/mr_pool.c b/drivers/infiniband/core/mr_pool.c new file mode 100644 index 0000000..b0a04c8 --- /dev/null +++ b/drivers/infiniband/core/mr_pool.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 HGST, a Western Digital Company. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#include +#include + +struct ib_mr *ib_mr_pool_get(struct ib_qp *qp) +{ + struct ib_mr *mr = NULL; + unsigned long flags; + + spin_lock_irqsave(&qp->mr_lock, flags); + mr = list_first_entry_or_null(&qp->free_mrs, struct ib_mr, qp_entry); + if (mr) + list_move(&mr->qp_entry, &qp->used_mrs); + spin_unlock_irqrestore(&qp->mr_lock, flags); + + return mr; +} +EXPORT_SYMBOL(ib_mr_pool_get); + +void ib_mr_pool_put(struct ib_qp *qp, struct ib_mr *mr) +{ + unsigned long flags; + + spin_lock_irqsave(&qp->mr_lock, flags); + list_move(&mr->qp_entry, &qp->free_mrs); + spin_unlock_irqrestore(&qp->mr_lock, flags); +} +EXPORT_SYMBOL(ib_mr_pool_put); + +int ib_mr_pool_init(struct ib_qp *qp, int nr, enum ib_mr_type type, + u32 max_num_sg) +{ + struct ib_mr *mr; + unsigned long flags; + int ret, i; + + for (i = 0; i < nr; i++) { + mr = ib_alloc_mr(qp->pd, type, max_num_sg); + if (IS_ERR(mr)) { + ret = PTR_ERR(mr); + goto out; + } + + spin_lock_irqsave(&qp->mr_lock, flags); + list_add_tail(&mr->qp_entry, &qp->free_mrs); + spin_unlock_irqrestore(&qp->mr_lock, flags); + } + + return 0; +out: + ib_mr_pool_destroy(qp); + return ret; +} +EXPORT_SYMBOL(ib_mr_pool_init); + +void ib_mr_pool_destroy(struct ib_qp *qp) +{ + struct ib_mr *mr; + unsigned long flags; + + WARN_ON_ONCE(!list_empty(&qp->used_mrs)); + + spin_lock_irqsave(&qp->mr_lock, flags); + while (!list_empty(&qp->free_mrs)) { + mr = list_first_entry(&qp->free_mrs, struct ib_mr, qp_entry); + list_del(&mr->qp_entry); + + spin_unlock_irqrestore(&qp->mr_lock, flags); + ib_dereg_mr(mr); + spin_lock_irqsave(&qp->mr_lock, flags); + } + spin_unlock_irqrestore(&qp->mr_lock, flags); +} +EXPORT_SYMBOL(ib_mr_pool_destroy); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 31b82cd..879839f 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -738,6 +738,10 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, qp->uobject = NULL; qp->qp_type = qp_init_attr->qp_type; + spin_lock_init(&qp->mr_lock); + INIT_LIST_HEAD(&qp->free_mrs); + INIT_LIST_HEAD(&qp->used_mrs); + atomic_set(&qp->usecnt, 0); if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { qp->event_handler = __ib_shared_qp_event_handler; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index d8533ab..380d03d 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1408,6 +1408,11 @@ struct ib_qp { struct ib_srq *srq; struct ib_xrcd *xrcd; /* XRC TGT QPs only */ struct list_head xrcd_list; + + spinlock_t mr_lock; + struct list_head free_mrs; + struct list_head used_mrs; + /* count times opened, mcast attaches, flow attaches */ atomic_t usecnt; struct list_head open_list; @@ -1422,12 +1427,15 @@ struct ib_qp { struct ib_mr { struct ib_device *device; struct ib_pd *pd; - struct ib_uobject *uobject; u32 lkey; u32 rkey; u64 iova; u32 length; unsigned int page_size; + union { + struct ib_uobject *uobject; /* user */ + struct list_head qp_entry; /* FR */ + }; }; struct ib_mw { diff --git a/include/rdma/mr_pool.h b/include/rdma/mr_pool.h new file mode 100644 index 0000000..b4ee196 --- /dev/null +++ b/include/rdma/mr_pool.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016 HGST, a Western Digital Company. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ +#include + +struct ib_mr *ib_mr_pool_get(struct ib_qp *qp); +void ib_mr_pool_put(struct ib_qp *qp, struct ib_mr *mr); + +int ib_mr_pool_init(struct ib_qp *qp, int nr, enum ib_mr_type type, + u32 max_num_sg); +void ib_mr_pool_destroy(struct ib_qp *qp);