Skip to content

Commit 1a40c36

Browse files
mrgolinrleon
authored andcommitted
RDMA/uverbs: Add a common way to create CQ with umem
Add ioctl command attributes and a common handling for the option to create CQs with memory buffers passed from userspace. When required attributes are supplied, create umem and provide it for driver's use. The extension enables creation of CQs on top of preallocated CPU virtual or device memory buffers, by supplying VA or dmabuf fd, in a common way. Drivers can support this flow by initializing a new create_cq_umem fp field in their ops struct, with a function that can handle the new parameter. Signed-off-by: Michael Margolin <[email protected]> Link: https://patch.msgid.link/[email protected] Reviewed-by: Jason Gunthorpe <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]>
1 parent e73242a commit 1a40c36

File tree

4 files changed

+90
-6
lines changed

4 files changed

+90
-6
lines changed

drivers/infiniband/core/device.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2728,6 +2728,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
27282728
SET_DEVICE_OP(dev_ops, create_ah);
27292729
SET_DEVICE_OP(dev_ops, create_counters);
27302730
SET_DEVICE_OP(dev_ops, create_cq);
2731+
SET_DEVICE_OP(dev_ops, create_cq_umem);
27312732
SET_DEVICE_OP(dev_ops, create_flow);
27322733
SET_DEVICE_OP(dev_ops, create_qp);
27332734
SET_DEVICE_OP(dev_ops, create_rwq_ind_table);

drivers/infiniband/core/uverbs_std_types_cq.c

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,21 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
6464
struct ib_ucq_object *obj = container_of(
6565
uverbs_attr_get_uobject(attrs, UVERBS_ATTR_CREATE_CQ_HANDLE),
6666
typeof(*obj), uevent.uobject);
67+
struct ib_uverbs_completion_event_file *ev_file = NULL;
6768
struct ib_device *ib_dev = attrs->context->device;
68-
int ret;
69-
u64 user_handle;
69+
struct ib_umem_dmabuf *umem_dmabuf;
7070
struct ib_cq_init_attr attr = {};
71-
struct ib_cq *cq;
72-
struct ib_uverbs_completion_event_file *ev_file = NULL;
7371
struct ib_uobject *ev_file_uobj;
72+
struct ib_umem *umem = NULL;
73+
u64 buffer_length;
74+
u64 buffer_offset;
75+
struct ib_cq *cq;
76+
u64 user_handle;
77+
u64 buffer_va;
78+
int buffer_fd;
79+
int ret;
7480

75-
if (!ib_dev->ops.create_cq || !ib_dev->ops.destroy_cq)
81+
if ((!ib_dev->ops.create_cq && !ib_dev->ops.create_cq_umem) || !ib_dev->ops.destroy_cq)
7682
return -EOPNOTSUPP;
7783

7884
ret = uverbs_copy_from(&attr.comp_vector, attrs,
@@ -112,9 +118,66 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
112118
INIT_LIST_HEAD(&obj->comp_list);
113119
INIT_LIST_HEAD(&obj->uevent.event_list);
114120

121+
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA)) {
122+
123+
ret = uverbs_copy_from(&buffer_va, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA);
124+
if (ret)
125+
goto err_event_file;
126+
127+
ret = uverbs_copy_from(&buffer_length, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
128+
if (ret)
129+
goto err_event_file;
130+
131+
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD) ||
132+
uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
133+
!ib_dev->ops.create_cq_umem) {
134+
ret = -EINVAL;
135+
goto err_event_file;
136+
}
137+
138+
umem = ib_umem_get(ib_dev, buffer_va, buffer_length, IB_ACCESS_LOCAL_WRITE);
139+
if (IS_ERR(umem)) {
140+
ret = PTR_ERR(umem);
141+
goto err_event_file;
142+
}
143+
} else if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD)) {
144+
145+
ret = uverbs_get_raw_fd(&buffer_fd, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD);
146+
if (ret)
147+
goto err_event_file;
148+
149+
ret = uverbs_copy_from(&buffer_offset, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET);
150+
if (ret)
151+
goto err_event_file;
152+
153+
ret = uverbs_copy_from(&buffer_length, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
154+
if (ret)
155+
goto err_event_file;
156+
157+
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA) ||
158+
!ib_dev->ops.create_cq_umem) {
159+
ret = -EINVAL;
160+
goto err_event_file;
161+
}
162+
163+
umem_dmabuf = ib_umem_dmabuf_get_pinned(ib_dev, buffer_offset, buffer_length,
164+
buffer_fd, IB_ACCESS_LOCAL_WRITE);
165+
if (IS_ERR(umem_dmabuf)) {
166+
ret = PTR_ERR(umem_dmabuf);
167+
goto err_event_file;
168+
}
169+
umem = &umem_dmabuf->umem;
170+
} else if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
171+
uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH) ||
172+
!ib_dev->ops.create_cq) {
173+
ret = -EINVAL;
174+
goto err_event_file;
175+
}
176+
115177
cq = rdma_zalloc_drv_obj(ib_dev, ib_cq);
116178
if (!cq) {
117179
ret = -ENOMEM;
180+
ib_umem_release(umem);
118181
goto err_event_file;
119182
}
120183

@@ -128,7 +191,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
128191
rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ);
129192
rdma_restrack_set_name(&cq->res, NULL);
130193

131-
ret = ib_dev->ops.create_cq(cq, &attr, attrs);
194+
ret = umem ? ib_dev->ops.create_cq_umem(cq, &attr, umem, attrs) :
195+
ib_dev->ops.create_cq(cq, &attr, attrs);
132196
if (ret)
133197
goto err_free;
134198

@@ -180,6 +244,17 @@ DECLARE_UVERBS_NAMED_METHOD(
180244
UVERBS_OBJECT_ASYNC_EVENT,
181245
UVERBS_ACCESS_READ,
182246
UA_OPTIONAL),
247+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_CQ_BUFFER_VA,
248+
UVERBS_ATTR_TYPE(u64),
249+
UA_OPTIONAL),
250+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH,
251+
UVERBS_ATTR_TYPE(u64),
252+
UA_OPTIONAL),
253+
UVERBS_ATTR_RAW_FD(UVERBS_ATTR_CREATE_CQ_BUFFER_FD,
254+
UA_OPTIONAL),
255+
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET,
256+
UVERBS_ATTR_TYPE(u64),
257+
UA_OPTIONAL),
183258
UVERBS_ATTR_UHW());
184259

185260
static int UVERBS_HANDLER(UVERBS_METHOD_CQ_DESTROY)(

include/rdma/ib_verbs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2486,6 +2486,10 @@ struct ib_device_ops {
24862486
int (*destroy_qp)(struct ib_qp *qp, struct ib_udata *udata);
24872487
int (*create_cq)(struct ib_cq *cq, const struct ib_cq_init_attr *attr,
24882488
struct uverbs_attr_bundle *attrs);
2489+
int (*create_cq_umem)(struct ib_cq *cq,
2490+
const struct ib_cq_init_attr *attr,
2491+
struct ib_umem *umem,
2492+
struct uverbs_attr_bundle *attrs);
24892493
int (*modify_cq)(struct ib_cq *cq, u16 cq_count, u16 cq_period);
24902494
int (*destroy_cq)(struct ib_cq *cq, struct ib_udata *udata);
24912495
int (*resize_cq)(struct ib_cq *cq, int cqe, struct ib_udata *udata);

include/uapi/rdma/ib_user_ioctl_cmds.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ enum uverbs_attrs_create_cq_cmd_attr_ids {
105105
UVERBS_ATTR_CREATE_CQ_FLAGS,
106106
UVERBS_ATTR_CREATE_CQ_RESP_CQE,
107107
UVERBS_ATTR_CREATE_CQ_EVENT_FD,
108+
UVERBS_ATTR_CREATE_CQ_BUFFER_VA,
109+
UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH,
110+
UVERBS_ATTR_CREATE_CQ_BUFFER_FD,
111+
UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET,
108112
};
109113

110114
enum uverbs_attrs_destroy_cq_cmd_attr_ids {

0 commit comments

Comments
 (0)