aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2011-05-25 20:08:38 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-13 12:29:18 -0400
commit8541f8de0583f562c652008a4e7a65e537842a7e (patch)
treeaf4e70e38a18534cf30d311aebc18e15285265a5
parent53d0bd1e7ff2fc626321f337c609fb76ae5d12c9 (diff)
RDMA/uverbs: Export XRC SRQs to user space
We require additional information to create XRC SRQs than we can exchange using the existing create SRQ ABI. Provide an enhanced create ABI for extended SRQ types. Based on patches by Jack Morgenstein <jackm@dev.mellanox.co.il> and Roland Dreier <roland@purestorage.com> Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-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
-rw-r--r--include/rdma/ib_user_verbs.h19
4 files changed, 156 insertions, 42 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);
diff --git a/include/rdma/ib_user_verbs.h b/include/rdma/ib_user_verbs.h
index b5cb63f41f0f..100abbbd6e6e 100644
--- a/include/rdma/ib_user_verbs.h
+++ b/include/rdma/ib_user_verbs.h
@@ -83,7 +83,8 @@ enum {
83 IB_USER_VERBS_CMD_DESTROY_SRQ, 83 IB_USER_VERBS_CMD_DESTROY_SRQ,
84 IB_USER_VERBS_CMD_POST_SRQ_RECV, 84 IB_USER_VERBS_CMD_POST_SRQ_RECV,
85 IB_USER_VERBS_CMD_OPEN_XRCD, 85 IB_USER_VERBS_CMD_OPEN_XRCD,
86 IB_USER_VERBS_CMD_CLOSE_XRCD 86 IB_USER_VERBS_CMD_CLOSE_XRCD,
87 IB_USER_VERBS_CMD_CREATE_XSRQ
87}; 88};
88 89
89/* 90/*
@@ -665,11 +666,25 @@ struct ib_uverbs_create_srq {
665 __u64 driver_data[0]; 666 __u64 driver_data[0];
666}; 667};
667 668
669struct ib_uverbs_create_xsrq {
670 __u64 response;
671 __u64 user_handle;
672 __u32 srq_type;
673 __u32 pd_handle;
674 __u32 max_wr;
675 __u32 max_sge;
676 __u32 srq_limit;
677 __u32 reserved;
678 __u32 xrcd_handle;
679 __u32 cq_handle;
680 __u64 driver_data[0];
681};
682
668struct ib_uverbs_create_srq_resp { 683struct ib_uverbs_create_srq_resp {
669 __u32 srq_handle; 684 __u32 srq_handle;
670 __u32 max_wr; 685 __u32 max_wr;
671 __u32 max_sge; 686 __u32 max_sge;
672 __u32 reserved; 687 __u32 srqn;
673}; 688};
674 689
675struct ib_uverbs_modify_srq { 690struct ib_uverbs_modify_srq {