diff options
author | Sagi Grimberg <sagig@mellanox.com> | 2015-10-13 19:11:29 +0300 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2015-10-28 22:27:18 -0400 |
commit | 14fb4171ab1c298101697fe844dbf062ff6f4adf (patch) | |
tree | 3d6df7ba3637caa1865cde2b1963116512de7d2b /drivers/infiniband/hw/cxgb3/iwch_provider.c | |
parent | 2eaa1c5647a3fd21684120f63e414367055249c7 (diff) |
RDMA/cxgb3: Support the new memory registration API
Support the new memory registration API by allocating a
private page list array in iwch_mr and populate it when
iwch_map_mr_sg is invoked. Also, support IB_WR_REG_MR
by duplicating build_fastreg just take the needed information
from different places:
- page_size, iova, length (ib_mr)
- page array (iwch_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>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw/cxgb3/iwch_provider.c')
-rw-r--r-- | drivers/infiniband/hw/cxgb3/iwch_provider.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index 93308c45f298..f7b915378343 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -463,6 +463,7 @@ static int iwch_dereg_mr(struct ib_mr *ib_mr) return -EINVAL; mhp = to_iwch_mr(ib_mr); + kfree(mhp->pages); rhp = mhp->rhp; mmid = mhp->attr.stag >> 8; cxio_dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size, @@ -821,6 +822,12 @@ static struct ib_mr *iwch_alloc_mr(struct ib_pd *pd, if (!mhp) goto err; + mhp->pages = kcalloc(max_num_sg, sizeof(u64), GFP_KERNEL); + if (!mhp->pages) { + ret = -ENOMEM; + goto pl_err; + } + mhp->rhp = rhp; ret = iwch_alloc_pbl(mhp, max_num_sg); if (ret) @@ -847,11 +854,36 @@ err3: err2: iwch_free_pbl(mhp); err1: + kfree(mhp->pages); +pl_err: kfree(mhp); err: return ERR_PTR(ret); } +static int iwch_set_page(struct ib_mr *ibmr, u64 addr) +{ + struct iwch_mr *mhp = to_iwch_mr(ibmr); + + if (unlikely(mhp->npages == mhp->attr.pbl_size)) + return -ENOMEM; + + mhp->pages[mhp->npages++] = addr; + + return 0; +} + +static int iwch_map_mr_sg(struct ib_mr *ibmr, + struct scatterlist *sg, + int sg_nents) +{ + struct iwch_mr *mhp = to_iwch_mr(ibmr); + + mhp->npages = 0; + + return ib_sg_to_pages(ibmr, sg, sg_nents, iwch_set_page); +} + static struct ib_fast_reg_page_list *iwch_alloc_fastreg_pbl( struct ib_device *device, int page_list_len) @@ -1450,6 +1482,7 @@ int iwch_register_device(struct iwch_dev *dev) dev->ibdev.bind_mw = iwch_bind_mw; dev->ibdev.dealloc_mw = iwch_dealloc_mw; dev->ibdev.alloc_mr = iwch_alloc_mr; + dev->ibdev.map_mr_sg = iwch_map_mr_sg; dev->ibdev.alloc_fast_reg_page_list = iwch_alloc_fastreg_pbl; dev->ibdev.free_fast_reg_page_list = iwch_free_fastreg_pbl; dev->ibdev.attach_mcast = iwch_multicast_attach; |