diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/uverbs.h | 6 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 172 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 1 |
3 files changed, 139 insertions, 40 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index 461e2f357c1e..00ce032fcead 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -127,6 +127,11 @@ struct ib_uxrcd_object { | |||
127 | atomic_t refcnt; | 127 | atomic_t refcnt; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | struct ib_usrq_object { | ||
131 | struct ib_uevent_object uevent; | ||
132 | struct ib_uxrcd_object *uxrcd; | ||
133 | }; | ||
134 | |||
130 | struct ib_uqp_object { | 135 | struct ib_uqp_object { |
131 | struct ib_uevent_object uevent; | 136 | struct ib_uevent_object uevent; |
132 | struct list_head mcast_list; | 137 | struct list_head mcast_list; |
@@ -204,6 +209,7 @@ IB_UVERBS_DECLARE_CMD(create_srq); | |||
204 | IB_UVERBS_DECLARE_CMD(modify_srq); | 209 | IB_UVERBS_DECLARE_CMD(modify_srq); |
205 | IB_UVERBS_DECLARE_CMD(query_srq); | 210 | IB_UVERBS_DECLARE_CMD(query_srq); |
206 | IB_UVERBS_DECLARE_CMD(destroy_srq); | 211 | IB_UVERBS_DECLARE_CMD(destroy_srq); |
212 | IB_UVERBS_DECLARE_CMD(create_xsrq); | ||
207 | IB_UVERBS_DECLARE_CMD(open_xrcd); | 213 | IB_UVERBS_DECLARE_CMD(open_xrcd); |
208 | IB_UVERBS_DECLARE_CMD(close_xrcd); | 214 | IB_UVERBS_DECLARE_CMD(close_xrcd); |
209 | 215 | ||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index c8b2a843fa00..2e66b14acd43 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -1400,7 +1400,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1400 | rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? | 1400 | rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? |
1401 | scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1); | 1401 | scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1); |
1402 | 1402 | ||
1403 | if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { | 1403 | if (!pd || !scq || !rcq || |
1404 | (cmd.is_srq && (!srq || srq->srq_type != IB_SRQT_BASIC))) { | ||
1404 | ret = -EINVAL; | 1405 | ret = -EINVAL; |
1405 | goto err_put; | 1406 | goto err_put; |
1406 | } | 1407 | } |
@@ -2293,108 +2294,199 @@ out_put: | |||
2293 | return ret ? ret : in_len; | 2294 | return ret ? ret : in_len; |
2294 | } | 2295 | } |
2295 | 2296 | ||
2296 | ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, | 2297 | int __uverbs_create_xsrq(struct ib_uverbs_file *file, |
2297 | const char __user *buf, int in_len, | 2298 | struct ib_uverbs_create_xsrq *cmd, |
2298 | int out_len) | 2299 | struct ib_udata *udata) |
2299 | { | 2300 | { |
2300 | struct ib_uverbs_create_srq cmd; | ||
2301 | struct ib_uverbs_create_srq_resp resp; | 2301 | struct ib_uverbs_create_srq_resp resp; |
2302 | struct ib_udata udata; | 2302 | struct ib_usrq_object *obj; |
2303 | struct ib_uevent_object *obj; | ||
2304 | struct ib_pd *pd; | 2303 | struct ib_pd *pd; |
2305 | struct ib_srq *srq; | 2304 | struct ib_srq *srq; |
2305 | struct ib_uobject *uninitialized_var(xrcd_uobj); | ||
2306 | struct ib_srq_init_attr attr; | 2306 | struct ib_srq_init_attr attr; |
2307 | int ret; | 2307 | int ret; |
2308 | 2308 | ||
2309 | if (out_len < sizeof resp) | ||
2310 | return -ENOSPC; | ||
2311 | |||
2312 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
2313 | return -EFAULT; | ||
2314 | |||
2315 | INIT_UDATA(&udata, buf + sizeof cmd, | ||
2316 | (unsigned long) cmd.response + sizeof resp, | ||
2317 | in_len - sizeof cmd, out_len - sizeof resp); | ||
2318 | |||
2319 | obj = kmalloc(sizeof *obj, GFP_KERNEL); | 2309 | obj = kmalloc(sizeof *obj, GFP_KERNEL); |
2320 | if (!obj) | 2310 | if (!obj) |
2321 | return -ENOMEM; | 2311 | return -ENOMEM; |
2322 | 2312 | ||
2323 | init_uobj(&obj->uobject, cmd.user_handle, file->ucontext, &srq_lock_key); | 2313 | init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext, &srq_lock_key); |
2324 | down_write(&obj->uobject.mutex); | 2314 | down_write(&obj->uevent.uobject.mutex); |
2325 | 2315 | ||
2326 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 2316 | pd = idr_read_pd(cmd->pd_handle, file->ucontext); |
2327 | if (!pd) { | 2317 | if (!pd) { |
2328 | ret = -EINVAL; | 2318 | ret = -EINVAL; |
2329 | goto err; | 2319 | goto err; |
2330 | } | 2320 | } |
2331 | 2321 | ||
2322 | if (cmd->srq_type == IB_SRQT_XRC) { | ||
2323 | attr.ext.xrc.cq = idr_read_cq(cmd->cq_handle, file->ucontext, 0); | ||
2324 | if (!attr.ext.xrc.cq) { | ||
2325 | ret = -EINVAL; | ||
2326 | goto err_put_pd; | ||
2327 | } | ||
2328 | |||
2329 | attr.ext.xrc.xrcd = idr_read_xrcd(cmd->xrcd_handle, file->ucontext, &xrcd_uobj); | ||
2330 | if (!attr.ext.xrc.xrcd) { | ||
2331 | ret = -EINVAL; | ||
2332 | goto err_put_cq; | ||
2333 | } | ||
2334 | |||
2335 | obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject); | ||
2336 | atomic_inc(&obj->uxrcd->refcnt); | ||
2337 | } | ||
2338 | |||
2332 | attr.event_handler = ib_uverbs_srq_event_handler; | 2339 | attr.event_handler = ib_uverbs_srq_event_handler; |
2333 | attr.srq_context = file; | 2340 | attr.srq_context = file; |
2334 | attr.srq_type = IB_SRQT_BASIC; | 2341 | attr.srq_type = cmd->srq_type; |
2335 | attr.attr.max_wr = cmd.max_wr; | 2342 | attr.attr.max_wr = cmd->max_wr; |
2336 | attr.attr.max_sge = cmd.max_sge; | 2343 | attr.attr.max_sge = cmd->max_sge; |
2337 | attr.attr.srq_limit = cmd.srq_limit; | 2344 | attr.attr.srq_limit = cmd->srq_limit; |
2338 | 2345 | ||
2339 | obj->events_reported = 0; | 2346 | obj->uevent.events_reported = 0; |
2340 | INIT_LIST_HEAD(&obj->event_list); | 2347 | INIT_LIST_HEAD(&obj->uevent.event_list); |
2341 | 2348 | ||
2342 | srq = pd->device->create_srq(pd, &attr, &udata); | 2349 | srq = pd->device->create_srq(pd, &attr, udata); |
2343 | if (IS_ERR(srq)) { | 2350 | if (IS_ERR(srq)) { |
2344 | ret = PTR_ERR(srq); | 2351 | ret = PTR_ERR(srq); |
2345 | goto err_put; | 2352 | goto err_put; |
2346 | } | 2353 | } |
2347 | 2354 | ||
2348 | srq->device = pd->device; | 2355 | srq->device = pd->device; |
2349 | srq->pd = pd; | 2356 | srq->pd = pd; |
2350 | srq->uobject = &obj->uobject; | 2357 | srq->srq_type = cmd->srq_type; |
2358 | srq->uobject = &obj->uevent.uobject; | ||
2351 | srq->event_handler = attr.event_handler; | 2359 | srq->event_handler = attr.event_handler; |
2352 | srq->srq_context = attr.srq_context; | 2360 | srq->srq_context = attr.srq_context; |
2361 | |||
2362 | if (cmd->srq_type == IB_SRQT_XRC) { | ||
2363 | srq->ext.xrc.cq = attr.ext.xrc.cq; | ||
2364 | srq->ext.xrc.xrcd = attr.ext.xrc.xrcd; | ||
2365 | atomic_inc(&attr.ext.xrc.cq->usecnt); | ||
2366 | atomic_inc(&attr.ext.xrc.xrcd->usecnt); | ||
2367 | } | ||
2368 | |||
2353 | atomic_inc(&pd->usecnt); | 2369 | atomic_inc(&pd->usecnt); |
2354 | atomic_set(&srq->usecnt, 0); | 2370 | atomic_set(&srq->usecnt, 0); |
2355 | 2371 | ||
2356 | obj->uobject.object = srq; | 2372 | obj->uevent.uobject.object = srq; |
2357 | ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uobject); | 2373 | ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject); |
2358 | if (ret) | 2374 | if (ret) |
2359 | goto err_destroy; | 2375 | goto err_destroy; |
2360 | 2376 | ||
2361 | memset(&resp, 0, sizeof resp); | 2377 | memset(&resp, 0, sizeof resp); |
2362 | resp.srq_handle = obj->uobject.id; | 2378 | resp.srq_handle = obj->uevent.uobject.id; |
2363 | resp.max_wr = attr.attr.max_wr; | 2379 | resp.max_wr = attr.attr.max_wr; |
2364 | resp.max_sge = attr.attr.max_sge; | 2380 | resp.max_sge = attr.attr.max_sge; |
2381 | if (cmd->srq_type == IB_SRQT_XRC) | ||
2382 | resp.srqn = srq->ext.xrc.srq_num; | ||
2365 | 2383 | ||
2366 | if (copy_to_user((void __user *) (unsigned long) cmd.response, | 2384 | if (copy_to_user((void __user *) (unsigned long) cmd->response, |
2367 | &resp, sizeof resp)) { | 2385 | &resp, sizeof resp)) { |
2368 | ret = -EFAULT; | 2386 | ret = -EFAULT; |
2369 | goto err_copy; | 2387 | goto err_copy; |
2370 | } | 2388 | } |
2371 | 2389 | ||
2390 | if (cmd->srq_type == IB_SRQT_XRC) { | ||
2391 | put_uobj_read(xrcd_uobj); | ||
2392 | put_cq_read(attr.ext.xrc.cq); | ||
2393 | } | ||
2372 | put_pd_read(pd); | 2394 | put_pd_read(pd); |
2373 | 2395 | ||
2374 | mutex_lock(&file->mutex); | 2396 | mutex_lock(&file->mutex); |
2375 | list_add_tail(&obj->uobject.list, &file->ucontext->srq_list); | 2397 | list_add_tail(&obj->uevent.uobject.list, &file->ucontext->srq_list); |
2376 | mutex_unlock(&file->mutex); | 2398 | mutex_unlock(&file->mutex); |
2377 | 2399 | ||
2378 | obj->uobject.live = 1; | 2400 | obj->uevent.uobject.live = 1; |
2379 | 2401 | ||
2380 | up_write(&obj->uobject.mutex); | 2402 | up_write(&obj->uevent.uobject.mutex); |
2381 | 2403 | ||
2382 | return in_len; | 2404 | return 0; |
2383 | 2405 | ||
2384 | err_copy: | 2406 | err_copy: |
2385 | idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uobject); | 2407 | idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject); |
2386 | 2408 | ||
2387 | err_destroy: | 2409 | err_destroy: |
2388 | ib_destroy_srq(srq); | 2410 | ib_destroy_srq(srq); |
2389 | 2411 | ||
2390 | err_put: | 2412 | err_put: |
2413 | if (cmd->srq_type == IB_SRQT_XRC) { | ||
2414 | atomic_dec(&obj->uxrcd->refcnt); | ||
2415 | put_uobj_read(xrcd_uobj); | ||
2416 | } | ||
2417 | |||
2418 | err_put_cq: | ||
2419 | if (cmd->srq_type == IB_SRQT_XRC) | ||
2420 | put_cq_read(attr.ext.xrc.cq); | ||
2421 | |||
2422 | err_put_pd: | ||
2391 | put_pd_read(pd); | 2423 | put_pd_read(pd); |
2392 | 2424 | ||
2393 | err: | 2425 | err: |
2394 | put_uobj_write(&obj->uobject); | 2426 | put_uobj_write(&obj->uevent.uobject); |
2395 | return ret; | 2427 | return ret; |
2396 | } | 2428 | } |
2397 | 2429 | ||
2430 | ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, | ||
2431 | const char __user *buf, int in_len, | ||
2432 | int out_len) | ||
2433 | { | ||
2434 | struct ib_uverbs_create_srq cmd; | ||
2435 | struct ib_uverbs_create_xsrq xcmd; | ||
2436 | struct ib_uverbs_create_srq_resp resp; | ||
2437 | struct ib_udata udata; | ||
2438 | int ret; | ||
2439 | |||
2440 | if (out_len < sizeof resp) | ||
2441 | return -ENOSPC; | ||
2442 | |||
2443 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
2444 | return -EFAULT; | ||
2445 | |||
2446 | xcmd.response = cmd.response; | ||
2447 | xcmd.user_handle = cmd.user_handle; | ||
2448 | xcmd.srq_type = IB_SRQT_BASIC; | ||
2449 | xcmd.pd_handle = cmd.pd_handle; | ||
2450 | xcmd.max_wr = cmd.max_wr; | ||
2451 | xcmd.max_sge = cmd.max_sge; | ||
2452 | xcmd.srq_limit = cmd.srq_limit; | ||
2453 | |||
2454 | INIT_UDATA(&udata, buf + sizeof cmd, | ||
2455 | (unsigned long) cmd.response + sizeof resp, | ||
2456 | in_len - sizeof cmd, out_len - sizeof resp); | ||
2457 | |||
2458 | ret = __uverbs_create_xsrq(file, &xcmd, &udata); | ||
2459 | if (ret) | ||
2460 | return ret; | ||
2461 | |||
2462 | return in_len; | ||
2463 | } | ||
2464 | |||
2465 | ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file, | ||
2466 | const char __user *buf, int in_len, int out_len) | ||
2467 | { | ||
2468 | struct ib_uverbs_create_xsrq cmd; | ||
2469 | struct ib_uverbs_create_srq_resp resp; | ||
2470 | struct ib_udata udata; | ||
2471 | int ret; | ||
2472 | |||
2473 | if (out_len < sizeof resp) | ||
2474 | return -ENOSPC; | ||
2475 | |||
2476 | if (copy_from_user(&cmd, buf, sizeof cmd)) | ||
2477 | return -EFAULT; | ||
2478 | |||
2479 | INIT_UDATA(&udata, buf + sizeof cmd, | ||
2480 | (unsigned long) cmd.response + sizeof resp, | ||
2481 | in_len - sizeof cmd, out_len - sizeof resp); | ||
2482 | |||
2483 | ret = __uverbs_create_xsrq(file, &cmd, &udata); | ||
2484 | if (ret) | ||
2485 | return ret; | ||
2486 | |||
2487 | return in_len; | ||
2488 | } | ||
2489 | |||
2398 | ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, | 2490 | ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, |
2399 | const char __user *buf, int in_len, | 2491 | const char __user *buf, int in_len, |
2400 | int out_len) | 2492 | int out_len) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index bb9dcea8fede..6ad221b87158 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -110,6 +110,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
110 | [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, | 110 | [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq, |
111 | [IB_USER_VERBS_CMD_OPEN_XRCD] = ib_uverbs_open_xrcd, | 111 | [IB_USER_VERBS_CMD_OPEN_XRCD] = ib_uverbs_open_xrcd, |
112 | [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrcd, | 112 | [IB_USER_VERBS_CMD_CLOSE_XRCD] = ib_uverbs_close_xrcd, |
113 | [IB_USER_VERBS_CMD_CREATE_XSRQ] = ib_uverbs_create_xsrq | ||
113 | }; | 114 | }; |
114 | 115 | ||
115 | static void ib_uverbs_add_one(struct ib_device *device); | 116 | static void ib_uverbs_add_one(struct ib_device *device); |