Skip to content

Commit be934cc

Browse files
Awik84jgunthorpe
authored andcommitted
IB/uverbs: Add device memory registration ioctl support
Adding new ioctl method for the MR object - REG_DM_MR. This command can be used by users to register an allocated device memory buffer as an MR and receive lkey and rkey to be used within work requests. It is added as a new method under the MR object and using a new ib_device callback - reg_dm_mr. The command creates a standard ib_mr object which represents the registered memory. Signed-off-by: Ariel Levkovich <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent bee76d7 commit be934cc

File tree

7 files changed

+193
-12
lines changed

7 files changed

+193
-12
lines changed

drivers/infiniband/core/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ ib_ucm-y := ucm.o
3535
ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o \
3636
rdma_core.o uverbs_std_types.o uverbs_ioctl.o \
3737
uverbs_ioctl_merge.o uverbs_std_types_cq.o \
38-
uverbs_std_types_flow_action.o uverbs_std_types_dm.o
38+
uverbs_std_types_flow_action.o uverbs_std_types_dm.o \
39+
uverbs_std_types_mr.o

drivers/infiniband/core/uverbs_std_types.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,6 @@ static int uverbs_free_srq(struct ib_uobject *uobject,
144144
return ret;
145145
}
146146

147-
static int uverbs_free_mr(struct ib_uobject *uobject,
148-
enum rdma_remove_reason why)
149-
{
150-
return ib_dereg_mr((struct ib_mr *)uobject->object);
151-
}
152-
153147
static int uverbs_free_xrcd(struct ib_uobject *uobject,
154148
enum rdma_remove_reason why)
155149
{
@@ -265,10 +259,6 @@ DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_QP,
265259
DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_MW,
266260
&UVERBS_TYPE_ALLOC_IDR(0, uverbs_free_mw));
267261

268-
DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_MR,
269-
/* 1 is used in order to free the MR after all the MWs */
270-
&UVERBS_TYPE_ALLOC_IDR(1, uverbs_free_mr));
271-
272262
DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_SRQ,
273263
&UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_usrq_object), 0,
274264
uverbs_free_srq));
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
3+
*
4+
* This software is available to you under a choice of one of two
5+
* licenses. You may choose to be licensed under the terms of the GNU
6+
* General Public License (GPL) Version 2, available from the file
7+
* COPYING in the main directory of this source tree, or the
8+
* OpenIB.org BSD license below:
9+
*
10+
* Redistribution and use in source and binary forms, with or
11+
* without modification, are permitted provided that the following
12+
* conditions are met:
13+
*
14+
* - Redistributions of source code must retain the above
15+
* copyright notice, this list of conditions and the following
16+
* disclaimer.
17+
*
18+
* - Redistributions in binary form must reproduce the above
19+
* copyright notice, this list of conditions and the following
20+
* disclaimer in the documentation and/or other materials
21+
* provided with the distribution.
22+
*
23+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30+
* SOFTWARE.
31+
*/
32+
33+
#include "uverbs.h"
34+
#include <rdma/uverbs_std_types.h>
35+
36+
static int uverbs_free_mr(struct ib_uobject *uobject,
37+
enum rdma_remove_reason why)
38+
{
39+
return ib_dereg_mr((struct ib_mr *)uobject->object);
40+
}
41+
42+
static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)(struct ib_device *ib_dev,
43+
struct ib_uverbs_file *file,
44+
struct uverbs_attr_bundle *attrs)
45+
{
46+
struct ib_dm_mr_attr attr = {};
47+
struct ib_uobject *uobj;
48+
struct ib_dm *dm;
49+
struct ib_pd *pd;
50+
struct ib_mr *mr;
51+
int ret;
52+
53+
if (!ib_dev->reg_dm_mr)
54+
return -EOPNOTSUPP;
55+
56+
ret = uverbs_copy_from(&attr.offset, attrs, UVERBS_ATTR_REG_DM_MR_OFFSET);
57+
if (ret)
58+
return ret;
59+
60+
ret = uverbs_copy_from(&attr.length, attrs,
61+
UVERBS_ATTR_REG_DM_MR_LENGTH);
62+
if (ret)
63+
return ret;
64+
65+
ret = uverbs_copy_from(&attr.access_flags, attrs,
66+
UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS);
67+
if (ret)
68+
return ret;
69+
70+
if (!(attr.access_flags & IB_ZERO_BASED))
71+
return -EINVAL;
72+
73+
ret = ib_check_mr_access(attr.access_flags);
74+
if (ret)
75+
return ret;
76+
77+
pd = uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DM_MR_PD_HANDLE);
78+
79+
dm = uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DM_MR_DM_HANDLE);
80+
81+
uobj = uverbs_attr_get(attrs, UVERBS_ATTR_REG_DM_MR_HANDLE)->obj_attr.uobject;
82+
83+
if (attr.offset > dm->length || attr.length > dm->length ||
84+
attr.length > dm->length - attr.offset)
85+
return -EINVAL;
86+
87+
mr = pd->device->reg_dm_mr(pd, dm, &attr, attrs);
88+
if (IS_ERR(mr))
89+
return PTR_ERR(mr);
90+
91+
mr->device = pd->device;
92+
mr->pd = pd;
93+
mr->dm = dm;
94+
mr->uobject = uobj;
95+
atomic_inc(&pd->usecnt);
96+
atomic_inc(&dm->usecnt);
97+
98+
uobj->object = mr;
99+
100+
ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DM_MR_RESP_LKEY, &mr->lkey,
101+
sizeof(mr->lkey));
102+
if (ret)
103+
goto err_dereg;
104+
105+
ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DM_MR_RESP_RKEY,
106+
&mr->rkey, sizeof(mr->rkey));
107+
if (ret)
108+
goto err_dereg;
109+
110+
return 0;
111+
112+
err_dereg:
113+
ib_dereg_mr(mr);
114+
115+
return ret;
116+
}
117+
118+
static DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_DM_MR_REG,
119+
&UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE, UVERBS_OBJECT_MR,
120+
UVERBS_ACCESS_NEW,
121+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
122+
&UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_OFFSET,
123+
UVERBS_ATTR_TYPE(u64),
124+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
125+
&UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_LENGTH,
126+
UVERBS_ATTR_TYPE(u64),
127+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
128+
&UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_PD_HANDLE, UVERBS_OBJECT_PD,
129+
UVERBS_ACCESS_READ,
130+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
131+
&UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS,
132+
UVERBS_ATTR_TYPE(u32),
133+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
134+
&UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_DM_HANDLE, UVERBS_OBJECT_DM,
135+
UVERBS_ACCESS_READ,
136+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
137+
&UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_DM_MR_RESP_LKEY,
138+
UVERBS_ATTR_TYPE(u32),
139+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
140+
&UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_REG_DM_MR_RESP_RKEY,
141+
UVERBS_ATTR_TYPE(u32),
142+
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
143+
144+
DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_MR,
145+
/* 1 is used in order to free the MR after all the MWs */
146+
&UVERBS_TYPE_ALLOC_IDR(1, uverbs_free_mr),
147+
&UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG));

drivers/infiniband/core/verbs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1616,12 +1616,16 @@ EXPORT_SYMBOL(ib_resize_cq);
16161616
int ib_dereg_mr(struct ib_mr *mr)
16171617
{
16181618
struct ib_pd *pd = mr->pd;
1619+
struct ib_dm *dm = mr->dm;
16191620
int ret;
16201621

16211622
rdma_restrack_del(&mr->res);
16221623
ret = mr->device->dereg_mr(mr);
1623-
if (!ret)
1624+
if (!ret) {
16241625
atomic_dec(&pd->usecnt);
1626+
if (dm)
1627+
atomic_dec(&dm->usecnt);
1628+
}
16251629

16261630
return ret;
16271631
}

include/rdma/ib_verbs.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,12 @@ struct ib_cq_caps {
321321
u16 max_cq_moderation_period;
322322
};
323323

324+
struct ib_dm_mr_attr {
325+
u64 length;
326+
u64 offset;
327+
u32 access_flags;
328+
};
329+
324330
struct ib_dm_alloc_attr {
325331
u64 length;
326332
u32 alignment;
@@ -1797,6 +1803,8 @@ struct ib_mr {
17971803
struct list_head qp_entry; /* FR */
17981804
};
17991805

1806+
struct ib_dm *dm;
1807+
18001808
/*
18011809
* Implementation details of the RDMA core, don't use in drivers:
18021810
*/
@@ -2444,6 +2452,9 @@ struct ib_device {
24442452
struct ib_dm_alloc_attr *attr,
24452453
struct uverbs_attr_bundle *attrs);
24462454
int (*dealloc_dm)(struct ib_dm *dm);
2455+
struct ib_mr * (*reg_dm_mr)(struct ib_pd *pd, struct ib_dm *dm,
2456+
struct ib_dm_mr_attr *attr,
2457+
struct uverbs_attr_bundle *attrs);
24472458
/**
24482459
* rdma netdev operation
24492460
*

include/rdma/uverbs_ioctl.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,18 @@ static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs
408408
return attr->ptr_attr.enum_id;
409409
}
410410

411+
static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_bundle,
412+
u16 idx)
413+
{
414+
struct ib_uobject *uobj =
415+
uverbs_attr_get(attrs_bundle, idx)->obj_attr.uobject;
416+
417+
if (IS_ERR(uobj))
418+
return uobj;
419+
420+
return uobj->object;
421+
}
422+
411423
static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
412424
size_t idx, const void *from, size_t size)
413425
{

include/uapi/rdma/ib_user_ioctl_cmds.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,20 @@ enum uverbs_methods_dm {
115115
UVERBS_METHOD_DM_ALLOC,
116116
UVERBS_METHOD_DM_FREE,
117117
};
118+
119+
enum uverbs_attrs_reg_dm_mr_cmd_attr_ids {
120+
UVERBS_ATTR_REG_DM_MR_HANDLE,
121+
UVERBS_ATTR_REG_DM_MR_OFFSET,
122+
UVERBS_ATTR_REG_DM_MR_LENGTH,
123+
UVERBS_ATTR_REG_DM_MR_PD_HANDLE,
124+
UVERBS_ATTR_REG_DM_MR_ACCESS_FLAGS,
125+
UVERBS_ATTR_REG_DM_MR_DM_HANDLE,
126+
UVERBS_ATTR_REG_DM_MR_RESP_LKEY,
127+
UVERBS_ATTR_REG_DM_MR_RESP_RKEY,
128+
};
129+
130+
enum uverbs_methods_mr {
131+
UVERBS_METHOD_DM_MR_REG,
132+
};
133+
118134
#endif

0 commit comments

Comments
 (0)