Skip to content

Commit

Permalink
IB/core: Introduce ib_reg_user_mr
Browse files Browse the repository at this point in the history
Add ib_reg_user_mr() for kernel ULPs to register user MRs.

The common use case that uses this function is a userspace application
that allocates memory for HCA access but the responsibility to register
the memory at the HCA is on an kernel ULP. This ULP that acts as an agent
for the userspace application.

This function is intended to be used without a user context so vendor
drivers need to be aware of calling reg_user_mr() device operation with
udata equal to NULL.

Among all drivers, i40iw is the only driver which relies on presence
of udata, so check udata existence for that driver.

Signed-off-by: Moni Shoua <[email protected]>
Reviewed-by: Guy Levi <[email protected]>
Signed-off-by: Leon Romanovsky <[email protected]>
  • Loading branch information
monis410 authored and Leon Romanovsky committed Jan 16, 2020
1 parent c320e52 commit 33006bd
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 1 deletion.
30 changes: 30 additions & 0 deletions drivers/infiniband/core/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,36 @@ EXPORT_SYMBOL(ib_resize_cq);

/* Memory regions */

struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
u64 virt_addr, int access_flags)
{
struct ib_mr *mr;

if (access_flags & IB_ACCESS_ON_DEMAND) {
if (!(pd->device->attrs.device_cap_flags &
IB_DEVICE_ON_DEMAND_PAGING)) {
pr_debug("ODP support not available\n");
return ERR_PTR(-EINVAL);
}
}

mr = pd->device->ops.reg_user_mr(pd, start, length, virt_addr,
access_flags, NULL);

if (IS_ERR(mr))
return mr;

mr->device = pd->device;
mr->pd = pd;
mr->dm = NULL;
atomic_inc(&pd->usecnt);
mr->res.type = RDMA_RESTRACK_MR;
rdma_restrack_kadd(&mr->res);

return mr;
}
EXPORT_SYMBOL(ib_reg_user_mr);

int ib_dereg_mr_user(struct ib_mr *mr, struct ib_udata *udata)
{
struct ib_pd *pd = mr->pd;
Expand Down
2 changes: 1 addition & 1 deletion drivers/infiniband/hw/efa/efa_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1358,7 +1358,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
int inline_size;
int err;

if (udata->inlen &&
if (udata && udata->inlen &&
!ib_is_udata_cleared(udata, 0, sizeof(udata->inlen))) {
ibdev_dbg(&dev->ibdev,
"Incompatible ABI params, udata not cleared\n");
Expand Down
3 changes: 3 additions & 0 deletions drivers/infiniband/hw/i40iw/i40iw_verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1756,6 +1756,9 @@ static struct ib_mr *i40iw_reg_user_mr(struct ib_pd *pd,
int ret;
int pg_shift;

if (!udata)
return ERR_PTR(-EOPNOTSUPP);

if (iwdev->closing)
return ERR_PTR(-ENODEV);

Expand Down
6 changes: 6 additions & 0 deletions include/rdma/ib_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4153,6 +4153,12 @@ static inline void ib_dma_free_coherent(struct ib_device *dev,
dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
}

/* ib_reg_user_mr - register a memory region for virtual addresses from kernel
* space. This function should be called when 'current' is the owning MM.
*/
struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
u64 virt_addr, int mr_access_flags);

/**
* ib_dereg_mr_user - Deregisters a memory region and removes it from the
* HCA translation table.
Expand Down

0 comments on commit 33006bd

Please sign in to comment.