Skip to content

Commit 5b2e450

Browse files
yishaihrleon
authored andcommitted
IB/core: Add UVERBS_METHOD_REG_MR on the MR object
This new method enables us to use a single ioctl from user space which supports the below variants of reg_mr [1]. The method will be extended in the next patches from the series with an extra attribute to let us pass DMA handle to be used as part of the registration. [1] ibv_reg_mr(), ibv_reg_mr_iova(), ibv_reg_mr_iova2(), ibv_reg_dmabuf_mr(). Signed-off-by: Yishai Hadas <[email protected]> Reviewed-by: Edward Srouji <[email protected]> Link: https://patch.msgid.link/5a3822ceef084efe967c9752e89c58d8250337c7.1752752567.git.leon@kernel.org Signed-off-by: Leon Romanovsky <[email protected]>
1 parent b272fc8 commit 5b2e450

File tree

2 files changed

+166
-1
lines changed

2 files changed

+166
-1
lines changed

drivers/infiniband/core/uverbs_std_types_mr.c

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,122 @@ static int UVERBS_HANDLER(UVERBS_METHOD_REG_DMABUF_MR)(
266266
return ret;
267267
}
268268

269+
static int UVERBS_HANDLER(UVERBS_METHOD_REG_MR)(
270+
struct uverbs_attr_bundle *attrs)
271+
{
272+
struct ib_uobject *uobj =
273+
uverbs_attr_get_uobject(attrs, UVERBS_ATTR_REG_MR_HANDLE);
274+
struct ib_pd *pd =
275+
uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_MR_PD_HANDLE);
276+
u32 valid_access_flags = IB_ACCESS_SUPPORTED;
277+
u64 length, iova, fd_offset = 0, addr = 0;
278+
struct ib_device *ib_dev = pd->device;
279+
bool has_fd_offset = false;
280+
bool has_addr = false;
281+
bool has_fd = false;
282+
u32 access_flags;
283+
struct ib_mr *mr;
284+
int fd;
285+
int ret;
286+
287+
ret = uverbs_copy_from(&iova, attrs, UVERBS_ATTR_REG_MR_IOVA);
288+
if (ret)
289+
return ret;
290+
291+
ret = uverbs_copy_from(&length, attrs, UVERBS_ATTR_REG_MR_LENGTH);
292+
if (ret)
293+
return ret;
294+
295+
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_REG_MR_ADDR)) {
296+
ret = uverbs_copy_from(&addr, attrs,
297+
UVERBS_ATTR_REG_MR_ADDR);
298+
if (ret)
299+
return ret;
300+
has_addr = true;
301+
}
302+
303+
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_REG_MR_FD_OFFSET)) {
304+
ret = uverbs_copy_from(&fd_offset, attrs,
305+
UVERBS_ATTR_REG_MR_FD_OFFSET);
306+
if (ret)
307+
return ret;
308+
has_fd_offset = true;
309+
}
310+
311+
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_REG_MR_FD)) {
312+
ret = uverbs_get_raw_fd(&fd, attrs,
313+
UVERBS_ATTR_REG_MR_FD);
314+
if (ret)
315+
return ret;
316+
has_fd = true;
317+
}
318+
319+
if (has_fd) {
320+
if (!ib_dev->ops.reg_user_mr_dmabuf)
321+
return -EOPNOTSUPP;
322+
323+
/* FD requires offset and can't come with addr */
324+
if (!has_fd_offset || has_addr)
325+
return -EINVAL;
326+
327+
if ((fd_offset & ~PAGE_MASK) != (iova & ~PAGE_MASK))
328+
return -EINVAL;
329+
330+
valid_access_flags = IB_ACCESS_LOCAL_WRITE |
331+
IB_ACCESS_REMOTE_READ |
332+
IB_ACCESS_REMOTE_WRITE |
333+
IB_ACCESS_REMOTE_ATOMIC |
334+
IB_ACCESS_RELAXED_ORDERING;
335+
} else {
336+
if (!has_addr || has_fd_offset)
337+
return -EINVAL;
338+
339+
if ((addr & ~PAGE_MASK) != (iova & ~PAGE_MASK))
340+
return -EINVAL;
341+
}
342+
343+
ret = uverbs_get_flags32(&access_flags, attrs,
344+
UVERBS_ATTR_REG_MR_ACCESS_FLAGS,
345+
valid_access_flags);
346+
if (ret)
347+
return ret;
348+
349+
ret = ib_check_mr_access(ib_dev, access_flags);
350+
if (ret)
351+
return ret;
352+
353+
if (has_fd)
354+
mr = pd->device->ops.reg_user_mr_dmabuf(pd, fd_offset, length, iova,
355+
fd, access_flags, attrs);
356+
else
357+
mr = pd->device->ops.reg_user_mr(pd, addr, length,
358+
iova, access_flags, NULL);
359+
360+
if (IS_ERR(mr))
361+
return PTR_ERR(mr);
362+
363+
mr->device = pd->device;
364+
mr->pd = pd;
365+
mr->type = IB_MR_TYPE_USER;
366+
mr->uobject = uobj;
367+
atomic_inc(&pd->usecnt);
368+
rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
369+
rdma_restrack_set_name(&mr->res, NULL);
370+
rdma_restrack_add(&mr->res);
371+
uobj->object = mr;
372+
373+
uverbs_finalize_uobj_create(attrs, UVERBS_ATTR_REG_MR_HANDLE);
374+
375+
ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_MR_RESP_LKEY,
376+
&mr->lkey, sizeof(mr->lkey));
377+
if (ret)
378+
return ret;
379+
380+
ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_MR_RESP_RKEY,
381+
&mr->rkey, sizeof(mr->rkey));
382+
return ret;
383+
}
384+
269385
DECLARE_UVERBS_NAMED_METHOD(
270386
UVERBS_METHOD_ADVISE_MR,
271387
UVERBS_ATTR_IDR(UVERBS_ATTR_ADVISE_MR_PD_HANDLE,
@@ -362,6 +478,40 @@ DECLARE_UVERBS_NAMED_METHOD(
362478
UVERBS_ATTR_TYPE(u32),
363479
UA_MANDATORY));
364480

481+
DECLARE_UVERBS_NAMED_METHOD(
482+
UVERBS_METHOD_REG_MR,
483+
UVERBS_ATTR_IDR(UVERBS_ATTR_REG_MR_HANDLE,
484+
UVERBS_OBJECT_MR,
485+
UVERBS_ACCESS_NEW,
486+
UA_MANDATORY),
487+
UVERBS_ATTR_IDR(UVERBS_ATTR_REG_MR_PD_HANDLE,
488+
UVERBS_OBJECT_PD,
489+
UVERBS_ACCESS_READ,
490+
UA_MANDATORY),
491+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_MR_IOVA,
492+
UVERBS_ATTR_TYPE(u64),
493+
UA_MANDATORY),
494+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_MR_LENGTH,
495+
UVERBS_ATTR_TYPE(u64),
496+
UA_MANDATORY),
497+
UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_REG_MR_ACCESS_FLAGS,
498+
enum ib_access_flags,
499+
UA_MANDATORY),
500+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_MR_ADDR,
501+
UVERBS_ATTR_TYPE(u64),
502+
UA_OPTIONAL),
503+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_MR_FD_OFFSET,
504+
UVERBS_ATTR_TYPE(u64),
505+
UA_OPTIONAL),
506+
UVERBS_ATTR_RAW_FD(UVERBS_ATTR_REG_MR_FD,
507+
UA_OPTIONAL),
508+
UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_MR_RESP_LKEY,
509+
UVERBS_ATTR_TYPE(u32),
510+
UA_MANDATORY),
511+
UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_MR_RESP_RKEY,
512+
UVERBS_ATTR_TYPE(u32),
513+
UA_MANDATORY));
514+
365515
DECLARE_UVERBS_NAMED_METHOD_DESTROY(
366516
UVERBS_METHOD_MR_DESTROY,
367517
UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_MR_HANDLE,
@@ -376,7 +526,8 @@ DECLARE_UVERBS_NAMED_OBJECT(
376526
&UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG),
377527
&UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY),
378528
&UVERBS_METHOD(UVERBS_METHOD_QUERY_MR),
379-
&UVERBS_METHOD(UVERBS_METHOD_REG_DMABUF_MR));
529+
&UVERBS_METHOD(UVERBS_METHOD_REG_DMABUF_MR),
530+
&UVERBS_METHOD(UVERBS_METHOD_REG_MR));
380531

381532
const struct uapi_definition uverbs_def_obj_mr[] = {
382533
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR,

include/uapi/rdma/ib_user_ioctl_cmds.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ enum uverbs_methods_mr {
257257
UVERBS_METHOD_ADVISE_MR,
258258
UVERBS_METHOD_QUERY_MR,
259259
UVERBS_METHOD_REG_DMABUF_MR,
260+
UVERBS_METHOD_REG_MR,
260261
};
261262

262263
enum uverbs_attrs_mr_destroy_ids {
@@ -290,6 +291,19 @@ enum uverbs_attrs_reg_dmabuf_mr_cmd_attr_ids {
290291
UVERBS_ATTR_REG_DMABUF_MR_RESP_RKEY,
291292
};
292293

294+
enum uverbs_attrs_reg_mr_cmd_attr_ids {
295+
UVERBS_ATTR_REG_MR_HANDLE,
296+
UVERBS_ATTR_REG_MR_PD_HANDLE,
297+
UVERBS_ATTR_REG_MR_IOVA,
298+
UVERBS_ATTR_REG_MR_ADDR,
299+
UVERBS_ATTR_REG_MR_LENGTH,
300+
UVERBS_ATTR_REG_MR_ACCESS_FLAGS,
301+
UVERBS_ATTR_REG_MR_FD,
302+
UVERBS_ATTR_REG_MR_FD_OFFSET,
303+
UVERBS_ATTR_REG_MR_RESP_LKEY,
304+
UVERBS_ATTR_REG_MR_RESP_RKEY,
305+
};
306+
293307
enum uverbs_attrs_create_counters_cmd_attr_ids {
294308
UVERBS_ATTR_CREATE_COUNTERS_HANDLE,
295309
};

0 commit comments

Comments
 (0)