From: Sagi Grimberg <sagig@mellanox.com>
To: linux-rdma@vger.kernel.org
Cc: linux-nfs@vger.kernel.org, "Nicholas A. Bellinger" <nab@linux-iscsi.org>
Subject: [PATCH v2 08/26] IB/qib: Support the new memory registration API
Date: Thu, 24 Sep 2015 20:34:36 +0300 [thread overview]
Message-ID: <1443116094-7969-9-git-send-email-sagig@mellanox.com> (raw)
In-Reply-To: <1443116094-7969-1-git-send-email-sagig@mellanox.com>
Support the new memory registration API by allocating a
private page list array in qib_mr and populate it when
qib_map_mr_sg is invoked. Also, support IB_WR_REG_MR
by duplicating qib_fastreg_mr just take the needed information
from different places:
- page_size, iova, length (ib_mr)
- page array (qib_mr)
- key, access flags (ib_reg_wr)
The IB_WR_FAST_REG_MR handlers will be removed later when
all the ULPs will be converted.
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Acked-by: Christoph Hellwig <hch@lst.de>
---
drivers/infiniband/hw/qib/qib_keys.c | 56 +++++++++++++++++++++++++++++++++++
drivers/infiniband/hw/qib/qib_mr.c | 32 ++++++++++++++++++++
drivers/infiniband/hw/qib/qib_verbs.c | 9 +++++-
drivers/infiniband/hw/qib/qib_verbs.h | 8 +++++
4 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/qib/qib_keys.c b/drivers/infiniband/hw/qib/qib_keys.c
index eaf139a33b2e..95b8b9110fc6 100644
--- a/drivers/infiniband/hw/qib/qib_keys.c
+++ b/drivers/infiniband/hw/qib/qib_keys.c
@@ -390,3 +390,59 @@ bail:
spin_unlock_irqrestore(&rkt->lock, flags);
return ret;
}
+
+/*
+ * Initialize the memory region specified by the work request.
+ */
+int qib_reg_mr(struct qib_qp *qp, struct ib_reg_wr *wr)
+{
+ struct qib_lkey_table *rkt = &to_idev(qp->ibqp.device)->lk_table;
+ struct qib_pd *pd = to_ipd(qp->ibqp.pd);
+ struct qib_mr *mr = to_imr(wr->mr);
+ struct qib_mregion *mrg;
+ u32 key = wr->key;
+ unsigned i, n, m;
+ int ret = -EINVAL;
+ unsigned long flags;
+ u64 *page_list;
+ size_t ps;
+
+ spin_lock_irqsave(&rkt->lock, flags);
+ if (pd->user || key == 0)
+ goto bail;
+
+ mrg = rcu_dereference_protected(
+ rkt->table[(key >> (32 - ib_qib_lkey_table_size))],
+ lockdep_is_held(&rkt->lock));
+ if (unlikely(mrg == NULL || qp->ibqp.pd != mrg->pd))
+ goto bail;
+
+ if (mr->npages > mrg->max_segs)
+ goto bail;
+
+ ps = mr->ibmr.page_size;
+ if (mr->ibmr.length > ps * mr->npages)
+ goto bail;
+
+ mrg->user_base = mr->ibmr.iova;
+ mrg->iova = mr->ibmr.iova;
+ mrg->lkey = key;
+ mrg->length = mr->ibmr.length;
+ mrg->access_flags = wr->access;
+ page_list = mr->pages;
+ m = 0;
+ n = 0;
+ for (i = 0; i < mr->npages; i++) {
+ mrg->map[m]->segs[n].vaddr = (void *) page_list[i];
+ mrg->map[m]->segs[n].length = ps;
+ if (++n == QIB_SEGSZ) {
+ m++;
+ n = 0;
+ }
+ }
+
+ ret = 0;
+bail:
+ spin_unlock_irqrestore(&rkt->lock, flags);
+ return ret;
+}
diff --git a/drivers/infiniband/hw/qib/qib_mr.c b/drivers/infiniband/hw/qib/qib_mr.c
index 19220dcb9a3b..0fa4b0de8074 100644
--- a/drivers/infiniband/hw/qib/qib_mr.c
+++ b/drivers/infiniband/hw/qib/qib_mr.c
@@ -303,6 +303,7 @@ int qib_dereg_mr(struct ib_mr *ibmr)
int ret = 0;
unsigned long timeout;
+ kfree(mr->pages);
qib_free_lkey(&mr->mr);
qib_put_mr(&mr->mr); /* will set completion if last */
@@ -340,7 +341,38 @@ struct ib_mr *qib_alloc_mr(struct ib_pd *pd,
if (IS_ERR(mr))
return (struct ib_mr *)mr;
+ mr->pages = kcalloc(max_num_sg, sizeof(u64), GFP_KERNEL);
+ if (!mr->pages)
+ goto err;
+
return &mr->ibmr;
+
+err:
+ qib_dereg_mr(&mr->ibmr);
+ return ERR_PTR(-ENOMEM);
+}
+
+static int qib_set_page(struct ib_mr *ibmr, u64 addr)
+{
+ struct qib_mr *mr = to_imr(ibmr);
+
+ if (unlikely(mr->npages == mr->mr.max_segs))
+ return -ENOMEM;
+
+ mr->pages[mr->npages++] = addr;
+
+ return 0;
+}
+
+int qib_map_mr_sg(struct ib_mr *ibmr,
+ struct scatterlist *sg,
+ unsigned int sg_nents)
+{
+ struct qib_mr *mr = to_imr(ibmr);
+
+ mr->npages = 0;
+
+ return ib_sg_to_pages(ibmr, sg, sg_nents, qib_set_page);
}
struct ib_fast_reg_page_list *
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
index a6b0b098ff30..a1e53d7b662b 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.c
+++ b/drivers/infiniband/hw/qib/qib_verbs.c
@@ -362,7 +362,10 @@ static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr,
* undefined operations.
* Make sure buffer is large enough to hold the result for atomics.
*/
- if (wr->opcode == IB_WR_FAST_REG_MR) {
+ if (wr->opcode == IB_WR_REG_MR) {
+ if (qib_reg_mr(qp, reg_wr(wr)))
+ goto bail_inval;
+ } else if (wr->opcode == IB_WR_FAST_REG_MR) {
if (qib_fast_reg_mr(qp, wr))
goto bail_inval;
} else if (qp->ibqp.qp_type == IB_QPT_UC) {
@@ -401,6 +404,9 @@ static int qib_post_one_send(struct qib_qp *qp, struct ib_send_wr *wr,
if (qp->ibqp.qp_type != IB_QPT_UC &&
qp->ibqp.qp_type != IB_QPT_RC)
memcpy(&wqe->ud_wr, ud_wr(wr), sizeof(wqe->ud_wr));
+ else if (wr->opcode == IB_WR_REG_MR)
+ memcpy(&wqe->reg_wr, reg_wr(wr),
+ sizeof(wqe->reg_wr));
else if (wr->opcode == IB_WR_FAST_REG_MR)
memcpy(&wqe->fast_reg_wr, fast_reg_wr(wr),
sizeof(wqe->fast_reg_wr));
@@ -2260,6 +2266,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
ibdev->reg_user_mr = qib_reg_user_mr;
ibdev->dereg_mr = qib_dereg_mr;
ibdev->alloc_mr = qib_alloc_mr;
+ ibdev->map_mr_sg = qib_map_mr_sg;
ibdev->alloc_fast_reg_page_list = qib_alloc_fast_reg_page_list;
ibdev->free_fast_reg_page_list = qib_free_fast_reg_page_list;
ibdev->alloc_fmr = qib_alloc_fmr;
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h
index 8aa16851a5e6..dbc81c5761e3 100644
--- a/drivers/infiniband/hw/qib/qib_verbs.h
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -330,6 +330,8 @@ struct qib_mr {
struct ib_mr ibmr;
struct ib_umem *umem;
struct qib_mregion mr; /* must be last */
+ u64 *pages;
+ u32 npages;
};
/*
@@ -341,6 +343,7 @@ struct qib_swqe {
union {
struct ib_send_wr wr; /* don't use wr.sg_list */
struct ib_ud_wr ud_wr;
+ struct ib_reg_wr reg_wr;
struct ib_fast_reg_wr fast_reg_wr;
struct ib_rdma_wr rdma_wr;
struct ib_atomic_wr atomic_wr;
@@ -1044,12 +1047,17 @@ struct ib_mr *qib_alloc_mr(struct ib_pd *pd,
enum ib_mr_type mr_type,
u32 max_entries);
+int qib_map_mr_sg(struct ib_mr *ibmr,
+ struct scatterlist *sg,
+ unsigned int sg_nents);
+
struct ib_fast_reg_page_list *qib_alloc_fast_reg_page_list(
struct ib_device *ibdev, int page_list_len);
void qib_free_fast_reg_page_list(struct ib_fast_reg_page_list *pl);
int qib_fast_reg_mr(struct qib_qp *qp, struct ib_send_wr *wr);
+int qib_reg_mr(struct qib_qp *qp, struct ib_reg_wr *wr);
struct ib_fmr *qib_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
struct ib_fmr_attr *fmr_attr);
--
1.8.4.3
next prev parent reply other threads:[~2015-09-24 17:35 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1443116094-7969-1-git-send-email-sagig@mellanox.com>
2015-09-24 17:34 ` [PATCH v2 01/26] IB/core: Introduce new fast registration API Sagi Grimberg
2015-09-24 17:41 ` Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 02/26] IB/mlx5: Remove dead fmr code Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 03/26] IB/mlx5: Support the new memory registration API Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 04/26] IB/mlx4: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 05/26] RDMA/ocrdma: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 06/26] RDMA/cxgb3: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 07/26] iw_cxgb4: " Sagi Grimberg
2015-09-24 17:34 ` Sagi Grimberg [this message]
2015-09-24 17:34 ` [PATCH v2 09/26] RDMA/nes: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 10/26] IB/iser: Port to new fast " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 11/26] iser-target: Port to new memory " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 12/26] xprtrdma: " Sagi Grimberg
2015-09-25 16:51 ` Chuck Lever
2015-09-27 7:23 ` Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 13/26] svcrdma: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 14/26] RDS/IW: Convert " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 15/26] IB/srp: Split srp_map_sg Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 16/26] IB/srp: Convert to new registration API Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 17/26] IB/srp: Dont allocate a page vector when using fast_reg Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 18/26] IB/mlx5: Remove old FRWR API support Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 19/26] IB/mlx4: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 20/26] RDMA/ocrdma: Remove old FRWR API Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 21/26] RDMA/cxgb3: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 22/26] iw_cxgb4: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 23/26] IB/qib: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 24/26] RDMA/nes: " Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 25/26] IB/hfi1: Remove Old fast registraion API support Sagi Grimberg
2015-09-24 17:34 ` [PATCH v2 26/26] IB/core: Remove old fast registration API Sagi Grimberg
2015-09-24 17:34 [PATCH v2 00/26] New " Sagi Grimberg
2015-09-24 17:35 ` [PATCH v2 08/26] IB/qib: Support the new memory " Sagi Grimberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1443116094-7969-9-git-send-email-sagig@mellanox.com \
--to=sagig@mellanox.com \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=nab@linux-iscsi.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).