aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/uverbs.h6
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c172
-rw-r--r--drivers/infiniband/core/uverbs_main.c1
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
130struct ib_usrq_object {
131 struct ib_uevent_object uevent;
132 struct ib_uxrcd_object *uxrcd;
133};
134
130struct ib_uqp_object { 135struct 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);
204IB_UVERBS_DECLARE_CMD(modify_srq); 209IB_UVERBS_DECLARE_CMD(modify_srq);
205IB_UVERBS_DECLARE_CMD(query_srq); 210IB_UVERBS_DECLARE_CMD(query_srq);
206IB_UVERBS_DECLARE_CMD(destroy_srq); 211IB_UVERBS_DECLARE_CMD(destroy_srq);
212IB_UVERBS_DECLARE_CMD(create_xsrq);
207IB_UVERBS_DECLARE_CMD(open_xrcd); 213IB_UVERBS_DECLARE_CMD(open_xrcd);
208IB_UVERBS_DECLARE_CMD(close_xrcd); 214IB_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
2296ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, 2297int __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
2384err_copy: 2406err_copy:
2385 idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uobject); 2407 idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uevent.uobject);
2386 2408
2387err_destroy: 2409err_destroy:
2388 ib_destroy_srq(srq); 2410 ib_destroy_srq(srq);
2389 2411
2390err_put: 2412err_put:
2413 if (cmd->srq_type == IB_SRQT_XRC) {
2414 atomic_dec(&obj->uxrcd->refcnt);
2415 put_uobj_read(xrcd_uobj);
2416 }
2417
2418err_put_cq:
2419 if (cmd->srq_type == IB_SRQT_XRC)
2420 put_cq_read(attr.ext.xrc.cq);
2421
2422err_put_pd:
2391 put_pd_read(pd); 2423 put_pd_read(pd);
2392 2424
2393err: 2425err:
2394 put_uobj_write(&obj->uobject); 2426 put_uobj_write(&obj->uevent.uobject);
2395 return ret; 2427 return ret;
2396} 2428}
2397 2429
2430ssize_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
2465ssize_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
2398ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, 2490ssize_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
115static void ib_uverbs_add_one(struct ib_device *device); 116static void ib_uverbs_add_one(struct ib_device *device);