aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2017-08-03 09:07:05 -0400
committerDoug Ledford <dledford@redhat.com>2017-08-31 08:35:13 -0400
commit9ee79fce364216df35ec46e26d20780c3c1644cc (patch)
tree89f46e4596b1cb09719b9223199a30998c025cfa
parentd70724f149b107f8e4062320270d3d8b6713a1bb (diff)
IB/core: Add completion queue (cq) object actions
Adding CQ ioctl actions: 1. create_cq 2. destroy_cq This requires adding the following: 1. A specification describing the method a. Handler b. Attributes specification Each attribute is one of the following: a. PTR_IN - input data Note: This could be encoded inlined for data < 64bit b. PTR_OUT - response data c. IDR - idr based object d. FD - fd based object Blobs attributes (clauses a and b) contain their type, while objects specifications (clauses c and d) contains the expected object type (for example, the given id should be UVERBS_TYPE_PD) and the required access (READ, WRITE, NEW or DESTROY). If a NEW is required, the new object's id will be assigned to this attribute. All attributes could get UA_FLAGS attribute. Currently we support stating that an attribute is mandatory or that the specification size corresponds to a lower bound (and that this attribute could be extended). We currently add both default attributes and the two generic UHW_IN and UHW_OUT driver specific attributes. 2. Handler A handler gets a uverbs_attr_bundle. The handler developer uses uverbs_attr_get to fetch an attribute of a given id. Each of these attribute groups correspond to the specification group defined in the action (clauses 1.b and 1.c respectively). The indices of these arrays corresponds to the attribute ids declared in the specifications (clause 2). The handler is quite simple. It assumes the infrastructure fetched all objects and locked, created or destroyed them as required by the specification. Pointer (or blob) attributes were validated to match their required sizes. After the handler finished, the infrastructure commits or rollbacks the objects. Signed-off-by: Matan Barak <matanb@mellanox.com> Reviewed-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/core/uverbs_std_types.c138
-rw-r--r--include/uapi/rdma/ib_user_ioctl_verbs.h20
2 files changed, 157 insertions, 1 deletions
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index db66c18857e4..0a98579700ec 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -249,6 +249,140 @@ static void create_udata(struct uverbs_attr_bundle *ctx,
249 INIT_UDATA_BUF_OR_NULL(udata, inbuf, outbuf, inbuf_len, outbuf_len); 249 INIT_UDATA_BUF_OR_NULL(udata, inbuf, outbuf, inbuf_len, outbuf_len);
250} 250}
251 251
252static int uverbs_create_cq_handler(struct ib_device *ib_dev,
253 struct ib_uverbs_file *file,
254 struct uverbs_attr_bundle *attrs)
255{
256 struct ib_ucontext *ucontext = file->ucontext;
257 struct ib_ucq_object *obj;
258 struct ib_udata uhw;
259 int ret;
260 u64 user_handle;
261 struct ib_cq_init_attr attr = {};
262 struct ib_cq *cq;
263 struct ib_uverbs_completion_event_file *ev_file = NULL;
264 const struct uverbs_attr *ev_file_attr;
265 struct ib_uobject *ev_file_uobj;
266
267 if (!(ib_dev->uverbs_cmd_mask & 1ULL << IB_USER_VERBS_CMD_CREATE_CQ))
268 return -EOPNOTSUPP;
269
270 ret = uverbs_copy_from(&attr.comp_vector, attrs, CREATE_CQ_COMP_VECTOR);
271 if (!ret)
272 ret = uverbs_copy_from(&attr.cqe, attrs, CREATE_CQ_CQE);
273 if (!ret)
274 ret = uverbs_copy_from(&user_handle, attrs, CREATE_CQ_USER_HANDLE);
275 if (ret)
276 return ret;
277
278 /* Optional param, if it doesn't exist, we get -ENOENT and skip it */
279 if (uverbs_copy_from(&attr.flags, attrs, CREATE_CQ_FLAGS) == -EFAULT)
280 return -EFAULT;
281
282 ev_file_attr = uverbs_attr_get(attrs, CREATE_CQ_COMP_CHANNEL);
283 if (!IS_ERR(ev_file_attr)) {
284 ev_file_uobj = ev_file_attr->obj_attr.uobject;
285
286 ev_file = container_of(ev_file_uobj,
287 struct ib_uverbs_completion_event_file,
288 uobj_file.uobj);
289 uverbs_uobject_get(ev_file_uobj);
290 }
291
292 if (attr.comp_vector >= ucontext->ufile->device->num_comp_vectors) {
293 ret = -EINVAL;
294 goto err_event_file;
295 }
296
297 obj = container_of(uverbs_attr_get(attrs, CREATE_CQ_HANDLE)->obj_attr.uobject,
298 typeof(*obj), uobject);
299 obj->uverbs_file = ucontext->ufile;
300 obj->comp_events_reported = 0;
301 obj->async_events_reported = 0;
302 INIT_LIST_HEAD(&obj->comp_list);
303 INIT_LIST_HEAD(&obj->async_list);
304
305 /* Temporary, only until drivers get the new uverbs_attr_bundle */
306 create_udata(attrs, &uhw);
307
308 cq = ib_dev->create_cq(ib_dev, &attr, ucontext, &uhw);
309 if (IS_ERR(cq)) {
310 ret = PTR_ERR(cq);
311 goto err_event_file;
312 }
313
314 cq->device = ib_dev;
315 cq->uobject = &obj->uobject;
316 cq->comp_handler = ib_uverbs_comp_handler;
317 cq->event_handler = ib_uverbs_cq_event_handler;
318 cq->cq_context = &ev_file->ev_queue;
319 obj->uobject.object = cq;
320 obj->uobject.user_handle = user_handle;
321 atomic_set(&cq->usecnt, 0);
322
323 ret = uverbs_copy_to(attrs, CREATE_CQ_RESP_CQE, &cq->cqe);
324 if (ret)
325 goto err_cq;
326
327 return 0;
328err_cq:
329 ib_destroy_cq(cq);
330
331err_event_file:
332 if (ev_file)
333 uverbs_uobject_put(ev_file_uobj);
334 return ret;
335};
336
337static DECLARE_UVERBS_METHOD(
338 uverbs_method_cq_create, UVERBS_CQ_CREATE, uverbs_create_cq_handler,
339 &UVERBS_ATTR_IDR(CREATE_CQ_HANDLE, UVERBS_OBJECT_CQ, UVERBS_ACCESS_NEW,
340 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
341 &UVERBS_ATTR_PTR_IN(CREATE_CQ_CQE, u32,
342 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
343 &UVERBS_ATTR_PTR_IN(CREATE_CQ_USER_HANDLE, u64,
344 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
345 &UVERBS_ATTR_FD(CREATE_CQ_COMP_CHANNEL, UVERBS_OBJECT_COMP_CHANNEL,
346 UVERBS_ACCESS_READ),
347 &UVERBS_ATTR_PTR_IN(CREATE_CQ_COMP_VECTOR, u32,
348 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
349 &UVERBS_ATTR_PTR_IN(CREATE_CQ_FLAGS, u32),
350 &UVERBS_ATTR_PTR_OUT(CREATE_CQ_RESP_CQE, u32,
351 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
352 &uverbs_uhw_compat_in, &uverbs_uhw_compat_out);
353
354static int uverbs_destroy_cq_handler(struct ib_device *ib_dev,
355 struct ib_uverbs_file *file,
356 struct uverbs_attr_bundle *attrs)
357{
358 struct ib_uverbs_destroy_cq_resp resp;
359 struct ib_uobject *uobj =
360 uverbs_attr_get(attrs, DESTROY_CQ_HANDLE)->obj_attr.uobject;
361 struct ib_ucq_object *obj = container_of(uobj, struct ib_ucq_object,
362 uobject);
363 int ret;
364
365 if (!(ib_dev->uverbs_cmd_mask & 1ULL << IB_USER_VERBS_CMD_DESTROY_CQ))
366 return -EOPNOTSUPP;
367
368 ret = rdma_explicit_destroy(uobj);
369 if (ret)
370 return ret;
371
372 resp.comp_events_reported = obj->comp_events_reported;
373 resp.async_events_reported = obj->async_events_reported;
374
375 return uverbs_copy_to(attrs, DESTROY_CQ_RESP, &resp);
376}
377
378static DECLARE_UVERBS_METHOD(
379 uverbs_method_cq_destroy, UVERBS_CQ_DESTROY, uverbs_destroy_cq_handler,
380 &UVERBS_ATTR_IDR(DESTROY_CQ_HANDLE, UVERBS_OBJECT_CQ,
381 UVERBS_ACCESS_DESTROY,
382 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
383 &UVERBS_ATTR_PTR_OUT(DESTROY_CQ_RESP, struct ib_uverbs_destroy_cq_resp,
384 UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
385
252DECLARE_UVERBS_OBJECT(uverbs_object_comp_channel, 386DECLARE_UVERBS_OBJECT(uverbs_object_comp_channel,
253 UVERBS_OBJECT_COMP_CHANNEL, 387 UVERBS_OBJECT_COMP_CHANNEL,
254 &UVERBS_TYPE_ALLOC_FD(0, 388 &UVERBS_TYPE_ALLOC_FD(0,
@@ -259,7 +393,9 @@ DECLARE_UVERBS_OBJECT(uverbs_object_comp_channel,
259 393
260DECLARE_UVERBS_OBJECT(uverbs_object_cq, UVERBS_OBJECT_CQ, 394DECLARE_UVERBS_OBJECT(uverbs_object_cq, UVERBS_OBJECT_CQ,
261 &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_ucq_object), 0, 395 &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_ucq_object), 0,
262 uverbs_free_cq)); 396 uverbs_free_cq),
397 &uverbs_method_cq_create,
398 &uverbs_method_cq_destroy);
263 399
264DECLARE_UVERBS_OBJECT(uverbs_object_qp, UVERBS_OBJECT_QP, 400DECLARE_UVERBS_OBJECT(uverbs_object_qp, UVERBS_OBJECT_QP,
265 &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uqp_object), 0, 401 &UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uqp_object), 0,
diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h
index 90f81eeca35b..842792eae383 100644
--- a/include/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/include/uapi/rdma/ib_user_ioctl_verbs.h
@@ -60,5 +60,25 @@ enum {
60 UVERBS_UHW_OUT, 60 UVERBS_UHW_OUT,
61}; 61};
62 62
63enum uverbs_create_cq_cmd_attr_ids {
64 CREATE_CQ_HANDLE,
65 CREATE_CQ_CQE,
66 CREATE_CQ_USER_HANDLE,
67 CREATE_CQ_COMP_CHANNEL,
68 CREATE_CQ_COMP_VECTOR,
69 CREATE_CQ_FLAGS,
70 CREATE_CQ_RESP_CQE,
71};
72
73enum uverbs_destroy_cq_cmd_attr_ids {
74 DESTROY_CQ_HANDLE,
75 DESTROY_CQ_RESP,
76};
77
78enum uverbs_actions_cq_ops {
79 UVERBS_CQ_CREATE,
80 UVERBS_CQ_DESTROY,
81};
82
63#endif 83#endif
64 84