aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2006-06-17 23:44:49 -0400
committerRoland Dreier <rolandd@cisco.com>2006-06-17 23:44:49 -0400
commit9ead190bfde2a434c74ea604382d08acb2eceef5 (patch)
tree937f1bb8dedea56efc46aed12370bb3865898763
parentc93b6fbaa99bb3a1552e14317296be14dde51dfb (diff)
IB/uverbs: Don't serialize with ib_uverbs_idr_mutex
Currently, all userspace verbs operations that call into the kernel are serialized by ib_uverbs_idr_mutex. This can be a scalability issue for some workloads, especially for devices driven by the ipath driver, which needs to call into the kernel even for datapath operations. Fix this by adding reference counts to the userspace objects, and then converting ib_uverbs_idr_mutex into a spinlock that only protects the idrs long enough to take a reference on the object being looked up. Because remove operations may fail, we have to do a slightly funky two-step deletion, which is described in the comments at the top of uverbs_cmd.c. This also still leaves ib_uverbs_idr_lock as a single lock that is possibly subject to contention. However, the lock hold time will only be a single idr operation, so multiple threads should still be able to make progress, even if ib_uverbs_idr_lock is being ping-ponged. Surprisingly, these changes even shrink the object code: add/remove: 23/5 grow/shrink: 4/21 up/down: 633/-693 (-60) Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/core/uverbs.h4
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c890
-rw-r--r--drivers/infiniband/core/uverbs_main.c35
-rw-r--r--include/rdma/ib_verbs.h4
4 files changed, 557 insertions, 376 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 3372d67ff139..bb9bee56a824 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -132,7 +132,7 @@ struct ib_ucq_object {
132 u32 async_events_reported; 132 u32 async_events_reported;
133}; 133};
134 134
135extern struct mutex ib_uverbs_idr_mutex; 135extern spinlock_t ib_uverbs_idr_lock;
136extern struct idr ib_uverbs_pd_idr; 136extern struct idr ib_uverbs_pd_idr;
137extern struct idr ib_uverbs_mr_idr; 137extern struct idr ib_uverbs_mr_idr;
138extern struct idr ib_uverbs_mw_idr; 138extern struct idr ib_uverbs_mw_idr;
@@ -141,6 +141,8 @@ extern struct idr ib_uverbs_cq_idr;
141extern struct idr ib_uverbs_qp_idr; 141extern struct idr ib_uverbs_qp_idr;
142extern struct idr ib_uverbs_srq_idr; 142extern struct idr ib_uverbs_srq_idr;
143 143
144void idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj);
145
144struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, 146struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
145 int is_async, int *fd); 147 int is_async, int *fd);
146void ib_uverbs_release_event_file(struct kref *ref); 148void ib_uverbs_release_event_file(struct kref *ref);
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 403dd811ec7f..76bf61e9b552 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -50,7 +50,64 @@
50 (udata)->outlen = (olen); \ 50 (udata)->outlen = (olen); \
51 } while (0) 51 } while (0)
52 52
53static int idr_add_uobj(struct idr *idr, void *obj, struct ib_uobject *uobj) 53/*
54 * The ib_uobject locking scheme is as follows:
55 *
56 * - ib_uverbs_idr_lock protects the uverbs idrs themselves, so it
57 * needs to be held during all idr operations. When an object is
58 * looked up, a reference must be taken on the object's kref before
59 * dropping this lock.
60 *
61 * - Each object also has an rwsem. This rwsem must be held for
62 * reading while an operation that uses the object is performed.
63 * For example, while registering an MR, the associated PD's
64 * uobject.mutex must be held for reading. The rwsem must be held
65 * for writing while initializing or destroying an object.
66 *
67 * - In addition, each object has a "live" flag. If this flag is not
68 * set, then lookups of the object will fail even if it is found in
69 * the idr. This handles a reader that blocks and does not acquire
70 * the rwsem until after the object is destroyed. The destroy
71 * operation will set the live flag to 0 and then drop the rwsem;
72 * this will allow the reader to acquire the rwsem, see that the
73 * live flag is 0, and then drop the rwsem and its reference to
74 * object. The underlying storage will not be freed until the last
75 * reference to the object is dropped.
76 */
77
78static void init_uobj(struct ib_uobject *uobj, u64 user_handle,
79 struct ib_ucontext *context)
80{
81 uobj->user_handle = user_handle;
82 uobj->context = context;
83 kref_init(&uobj->ref);
84 init_rwsem(&uobj->mutex);
85 uobj->live = 0;
86}
87
88static void release_uobj(struct kref *kref)
89{
90 kfree(container_of(kref, struct ib_uobject, ref));
91}
92
93static void put_uobj(struct ib_uobject *uobj)
94{
95 kref_put(&uobj->ref, release_uobj);
96}
97
98static void put_uobj_read(struct ib_uobject *uobj)
99{
100 up_read(&uobj->mutex);
101 put_uobj(uobj);
102}
103
104static void put_uobj_write(struct ib_uobject *uobj)
105{
106 up_write(&uobj->mutex);
107 put_uobj(uobj);
108}
109
110static int idr_add_uobj(struct idr *idr, struct ib_uobject *uobj)
54{ 111{
55 int ret; 112 int ret;
56 113
@@ -58,7 +115,9 @@ retry:
58 if (!idr_pre_get(idr, GFP_KERNEL)) 115 if (!idr_pre_get(idr, GFP_KERNEL))
59 return -ENOMEM; 116 return -ENOMEM;
60 117
118 spin_lock(&ib_uverbs_idr_lock);
61 ret = idr_get_new(idr, uobj, &uobj->id); 119 ret = idr_get_new(idr, uobj, &uobj->id);
120 spin_unlock(&ib_uverbs_idr_lock);
62 121
63 if (ret == -EAGAIN) 122 if (ret == -EAGAIN)
64 goto retry; 123 goto retry;
@@ -66,6 +125,121 @@ retry:
66 return ret; 125 return ret;
67} 126}
68 127
128void idr_remove_uobj(struct idr *idr, struct ib_uobject *uobj)
129{
130 spin_lock(&ib_uverbs_idr_lock);
131 idr_remove(idr, uobj->id);
132 spin_unlock(&ib_uverbs_idr_lock);
133}
134
135static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
136 struct ib_ucontext *context)
137{
138 struct ib_uobject *uobj;
139
140 spin_lock(&ib_uverbs_idr_lock);
141 uobj = idr_find(idr, id);
142 if (uobj)
143 kref_get(&uobj->ref);
144 spin_unlock(&ib_uverbs_idr_lock);
145
146 return uobj;
147}
148
149static struct ib_uobject *idr_read_uobj(struct idr *idr, int id,
150 struct ib_ucontext *context)
151{
152 struct ib_uobject *uobj;
153
154 uobj = __idr_get_uobj(idr, id, context);
155 if (!uobj)
156 return NULL;
157
158 down_read(&uobj->mutex);
159 if (!uobj->live) {
160 put_uobj_read(uobj);
161 return NULL;
162 }
163
164 return uobj;
165}
166
167static struct ib_uobject *idr_write_uobj(struct idr *idr, int id,
168 struct ib_ucontext *context)
169{
170 struct ib_uobject *uobj;
171
172 uobj = __idr_get_uobj(idr, id, context);
173 if (!uobj)
174 return NULL;
175
176 down_write(&uobj->mutex);
177 if (!uobj->live) {
178 put_uobj_write(uobj);
179 return NULL;
180 }
181
182 return uobj;
183}
184
185static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context)
186{
187 struct ib_uobject *uobj;
188
189 uobj = idr_read_uobj(idr, id, context);
190 return uobj ? uobj->object : NULL;
191}
192
193static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context)
194{
195 return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context);
196}
197
198static void put_pd_read(struct ib_pd *pd)
199{
200 put_uobj_read(pd->uobject);
201}
202
203static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context)
204{
205 return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context);
206}
207
208static void put_cq_read(struct ib_cq *cq)
209{
210 put_uobj_read(cq->uobject);
211}
212
213static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context)
214{
215 return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context);
216}
217
218static void put_ah_read(struct ib_ah *ah)
219{
220 put_uobj_read(ah->uobject);
221}
222
223static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context)
224{
225 return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context);
226}
227
228static void put_qp_read(struct ib_qp *qp)
229{
230 put_uobj_read(qp->uobject);
231}
232
233static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context)
234{
235 return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context);
236}
237
238static void put_srq_read(struct ib_srq *srq)
239{
240 put_uobj_read(srq->uobject);
241}
242
69ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, 243ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
70 const char __user *buf, 244 const char __user *buf,
71 int in_len, int out_len) 245 int in_len, int out_len)
@@ -296,7 +470,8 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
296 if (!uobj) 470 if (!uobj)
297 return -ENOMEM; 471 return -ENOMEM;
298 472
299 uobj->context = file->ucontext; 473 init_uobj(uobj, 0, file->ucontext);
474 down_write(&uobj->mutex);
300 475
301 pd = file->device->ib_dev->alloc_pd(file->device->ib_dev, 476 pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
302 file->ucontext, &udata); 477 file->ucontext, &udata);
@@ -309,11 +484,10 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
309 pd->uobject = uobj; 484 pd->uobject = uobj;
310 atomic_set(&pd->usecnt, 0); 485 atomic_set(&pd->usecnt, 0);
311 486
312 mutex_lock(&ib_uverbs_idr_mutex); 487 uobj->object = pd;
313 488 ret = idr_add_uobj(&ib_uverbs_pd_idr, uobj);
314 ret = idr_add_uobj(&ib_uverbs_pd_idr, pd, uobj);
315 if (ret) 489 if (ret)
316 goto err_up; 490 goto err_idr;
317 491
318 memset(&resp, 0, sizeof resp); 492 memset(&resp, 0, sizeof resp);
319 resp.pd_handle = uobj->id; 493 resp.pd_handle = uobj->id;
@@ -321,26 +495,27 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
321 if (copy_to_user((void __user *) (unsigned long) cmd.response, 495 if (copy_to_user((void __user *) (unsigned long) cmd.response,
322 &resp, sizeof resp)) { 496 &resp, sizeof resp)) {
323 ret = -EFAULT; 497 ret = -EFAULT;
324 goto err_idr; 498 goto err_copy;
325 } 499 }
326 500
327 mutex_lock(&file->mutex); 501 mutex_lock(&file->mutex);
328 list_add_tail(&uobj->list, &file->ucontext->pd_list); 502 list_add_tail(&uobj->list, &file->ucontext->pd_list);
329 mutex_unlock(&file->mutex); 503 mutex_unlock(&file->mutex);
330 504
331 mutex_unlock(&ib_uverbs_idr_mutex); 505 uobj->live = 1;
506
507 up_write(&uobj->mutex);
332 508
333 return in_len; 509 return in_len;
334 510
335err_idr: 511err_copy:
336 idr_remove(&ib_uverbs_pd_idr, uobj->id); 512 idr_remove_uobj(&ib_uverbs_pd_idr, uobj);
337 513
338err_up: 514err_idr:
339 mutex_unlock(&ib_uverbs_idr_mutex);
340 ib_dealloc_pd(pd); 515 ib_dealloc_pd(pd);
341 516
342err: 517err:
343 kfree(uobj); 518 put_uobj_write(uobj);
344 return ret; 519 return ret;
345} 520}
346 521
@@ -349,37 +524,34 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
349 int in_len, int out_len) 524 int in_len, int out_len)
350{ 525{
351 struct ib_uverbs_dealloc_pd cmd; 526 struct ib_uverbs_dealloc_pd cmd;
352 struct ib_pd *pd;
353 struct ib_uobject *uobj; 527 struct ib_uobject *uobj;
354 int ret = -EINVAL; 528 int ret;
355 529
356 if (copy_from_user(&cmd, buf, sizeof cmd)) 530 if (copy_from_user(&cmd, buf, sizeof cmd))
357 return -EFAULT; 531 return -EFAULT;
358 532
359 mutex_lock(&ib_uverbs_idr_mutex); 533 uobj = idr_write_uobj(&ib_uverbs_pd_idr, cmd.pd_handle, file->ucontext);
534 if (!uobj)
535 return -EINVAL;
360 536
361 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 537 ret = ib_dealloc_pd(uobj->object);
362 if (!pd || pd->uobject->context != file->ucontext) 538 if (!ret)
363 goto out; 539 uobj->live = 0;
364 540
365 uobj = pd->uobject; 541 put_uobj_write(uobj);
366 542
367 ret = ib_dealloc_pd(pd);
368 if (ret) 543 if (ret)
369 goto out; 544 return ret;
370 545
371 idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); 546 idr_remove_uobj(&ib_uverbs_pd_idr, uobj);
372 547
373 mutex_lock(&file->mutex); 548 mutex_lock(&file->mutex);
374 list_del(&uobj->list); 549 list_del(&uobj->list);
375 mutex_unlock(&file->mutex); 550 mutex_unlock(&file->mutex);
376 551
377 kfree(uobj); 552 put_uobj(uobj);
378 553
379out: 554 return in_len;
380 mutex_unlock(&ib_uverbs_idr_mutex);
381
382 return ret ? ret : in_len;
383} 555}
384 556
385ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, 557ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
@@ -419,7 +591,8 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
419 if (!obj) 591 if (!obj)
420 return -ENOMEM; 592 return -ENOMEM;
421 593
422 obj->uobject.context = file->ucontext; 594 init_uobj(&obj->uobject, 0, file->ucontext);
595 down_write(&obj->uobject.mutex);
423 596
424 /* 597 /*
425 * We ask for writable memory if any access flags other than 598 * We ask for writable memory if any access flags other than
@@ -436,23 +609,14 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
436 609
437 obj->umem.virt_base = cmd.hca_va; 610 obj->umem.virt_base = cmd.hca_va;
438 611
439 mutex_lock(&ib_uverbs_idr_mutex); 612 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
440 613 if (!pd)
441 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 614 goto err_release;
442 if (!pd || pd->uobject->context != file->ucontext) {
443 ret = -EINVAL;
444 goto err_up;
445 }
446
447 if (!pd->device->reg_user_mr) {
448 ret = -ENOSYS;
449 goto err_up;
450 }
451 615
452 mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata); 616 mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);
453 if (IS_ERR(mr)) { 617 if (IS_ERR(mr)) {
454 ret = PTR_ERR(mr); 618 ret = PTR_ERR(mr);
455 goto err_up; 619 goto err_put;
456 } 620 }
457 621
458 mr->device = pd->device; 622 mr->device = pd->device;
@@ -461,43 +625,48 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
461 atomic_inc(&pd->usecnt); 625 atomic_inc(&pd->usecnt);
462 atomic_set(&mr->usecnt, 0); 626 atomic_set(&mr->usecnt, 0);
463 627
464 memset(&resp, 0, sizeof resp); 628 obj->uobject.object = mr;
465 resp.lkey = mr->lkey; 629 ret = idr_add_uobj(&ib_uverbs_mr_idr, &obj->uobject);
466 resp.rkey = mr->rkey;
467
468 ret = idr_add_uobj(&ib_uverbs_mr_idr, mr, &obj->uobject);
469 if (ret) 630 if (ret)
470 goto err_unreg; 631 goto err_unreg;
471 632
633 memset(&resp, 0, sizeof resp);
634 resp.lkey = mr->lkey;
635 resp.rkey = mr->rkey;
472 resp.mr_handle = obj->uobject.id; 636 resp.mr_handle = obj->uobject.id;
473 637
474 if (copy_to_user((void __user *) (unsigned long) cmd.response, 638 if (copy_to_user((void __user *) (unsigned long) cmd.response,
475 &resp, sizeof resp)) { 639 &resp, sizeof resp)) {
476 ret = -EFAULT; 640 ret = -EFAULT;
477 goto err_idr; 641 goto err_copy;
478 } 642 }
479 643
644 put_pd_read(pd);
645
480 mutex_lock(&file->mutex); 646 mutex_lock(&file->mutex);
481 list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); 647 list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
482 mutex_unlock(&file->mutex); 648 mutex_unlock(&file->mutex);
483 649
484 mutex_unlock(&ib_uverbs_idr_mutex); 650 obj->uobject.live = 1;
651
652 up_write(&obj->uobject.mutex);
485 653
486 return in_len; 654 return in_len;
487 655
488err_idr: 656err_copy:
489 idr_remove(&ib_uverbs_mr_idr, obj->uobject.id); 657 idr_remove_uobj(&ib_uverbs_mr_idr, &obj->uobject);
490 658
491err_unreg: 659err_unreg:
492 ib_dereg_mr(mr); 660 ib_dereg_mr(mr);
493 661
494err_up: 662err_put:
495 mutex_unlock(&ib_uverbs_idr_mutex); 663 put_pd_read(pd);
496 664
665err_release:
497 ib_umem_release(file->device->ib_dev, &obj->umem); 666 ib_umem_release(file->device->ib_dev, &obj->umem);
498 667
499err_free: 668err_free:
500 kfree(obj); 669 put_uobj_write(&obj->uobject);
501 return ret; 670 return ret;
502} 671}
503 672
@@ -507,37 +676,40 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
507{ 676{
508 struct ib_uverbs_dereg_mr cmd; 677 struct ib_uverbs_dereg_mr cmd;
509 struct ib_mr *mr; 678 struct ib_mr *mr;
679 struct ib_uobject *uobj;
510 struct ib_umem_object *memobj; 680 struct ib_umem_object *memobj;
511 int ret = -EINVAL; 681 int ret = -EINVAL;
512 682
513 if (copy_from_user(&cmd, buf, sizeof cmd)) 683 if (copy_from_user(&cmd, buf, sizeof cmd))
514 return -EFAULT; 684 return -EFAULT;
515 685
516 mutex_lock(&ib_uverbs_idr_mutex); 686 uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle, file->ucontext);
517 687 if (!uobj)
518 mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle); 688 return -EINVAL;
519 if (!mr || mr->uobject->context != file->ucontext)
520 goto out;
521 689
522 memobj = container_of(mr->uobject, struct ib_umem_object, uobject); 690 memobj = container_of(uobj, struct ib_umem_object, uobject);
691 mr = uobj->object;
523 692
524 ret = ib_dereg_mr(mr); 693 ret = ib_dereg_mr(mr);
694 if (!ret)
695 uobj->live = 0;
696
697 put_uobj_write(uobj);
698
525 if (ret) 699 if (ret)
526 goto out; 700 return ret;
527 701
528 idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); 702 idr_remove_uobj(&ib_uverbs_mr_idr, uobj);
529 703
530 mutex_lock(&file->mutex); 704 mutex_lock(&file->mutex);
531 list_del(&memobj->uobject.list); 705 list_del(&uobj->list);
532 mutex_unlock(&file->mutex); 706 mutex_unlock(&file->mutex);
533 707
534 ib_umem_release(file->device->ib_dev, &memobj->umem); 708 ib_umem_release(file->device->ib_dev, &memobj->umem);
535 kfree(memobj);
536 709
537out: 710 put_uobj(uobj);
538 mutex_unlock(&ib_uverbs_idr_mutex);
539 711
540 return ret ? ret : in_len; 712 return in_len;
541} 713}
542 714
543ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, 715ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
@@ -576,7 +748,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
576 struct ib_uverbs_create_cq cmd; 748 struct ib_uverbs_create_cq cmd;
577 struct ib_uverbs_create_cq_resp resp; 749 struct ib_uverbs_create_cq_resp resp;
578 struct ib_udata udata; 750 struct ib_udata udata;
579 struct ib_ucq_object *uobj; 751 struct ib_ucq_object *obj;
580 struct ib_uverbs_event_file *ev_file = NULL; 752 struct ib_uverbs_event_file *ev_file = NULL;
581 struct ib_cq *cq; 753 struct ib_cq *cq;
582 int ret; 754 int ret;
@@ -594,10 +766,13 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
594 if (cmd.comp_vector >= file->device->num_comp_vectors) 766 if (cmd.comp_vector >= file->device->num_comp_vectors)
595 return -EINVAL; 767 return -EINVAL;
596 768
597 uobj = kmalloc(sizeof *uobj, GFP_KERNEL); 769 obj = kmalloc(sizeof *obj, GFP_KERNEL);
598 if (!uobj) 770 if (!obj)
599 return -ENOMEM; 771 return -ENOMEM;
600 772
773 init_uobj(&obj->uobject, cmd.user_handle, file->ucontext);
774 down_write(&obj->uobject.mutex);
775
601 if (cmd.comp_channel >= 0) { 776 if (cmd.comp_channel >= 0) {
602 ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); 777 ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel);
603 if (!ev_file) { 778 if (!ev_file) {
@@ -606,63 +781,64 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
606 } 781 }
607 } 782 }
608 783
609 uobj->uobject.user_handle = cmd.user_handle; 784 obj->uverbs_file = file;
610 uobj->uobject.context = file->ucontext; 785 obj->comp_events_reported = 0;
611 uobj->uverbs_file = file; 786 obj->async_events_reported = 0;
612 uobj->comp_events_reported = 0; 787 INIT_LIST_HEAD(&obj->comp_list);
613 uobj->async_events_reported = 0; 788 INIT_LIST_HEAD(&obj->async_list);
614 INIT_LIST_HEAD(&uobj->comp_list);
615 INIT_LIST_HEAD(&uobj->async_list);
616 789
617 cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe, 790 cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
618 file->ucontext, &udata); 791 file->ucontext, &udata);
619 if (IS_ERR(cq)) { 792 if (IS_ERR(cq)) {
620 ret = PTR_ERR(cq); 793 ret = PTR_ERR(cq);
621 goto err; 794 goto err_file;
622 } 795 }
623 796
624 cq->device = file->device->ib_dev; 797 cq->device = file->device->ib_dev;
625 cq->uobject = &uobj->uobject; 798 cq->uobject = &obj->uobject;
626 cq->comp_handler = ib_uverbs_comp_handler; 799 cq->comp_handler = ib_uverbs_comp_handler;
627 cq->event_handler = ib_uverbs_cq_event_handler; 800 cq->event_handler = ib_uverbs_cq_event_handler;
628 cq->cq_context = ev_file; 801 cq->cq_context = ev_file;
629 atomic_set(&cq->usecnt, 0); 802 atomic_set(&cq->usecnt, 0);
630 803
631 mutex_lock(&ib_uverbs_idr_mutex); 804 obj->uobject.object = cq;
632 805 ret = idr_add_uobj(&ib_uverbs_cq_idr, &obj->uobject);
633 ret = idr_add_uobj(&ib_uverbs_cq_idr, cq, &uobj->uobject);
634 if (ret) 806 if (ret)
635 goto err_up; 807 goto err_free;
636 808
637 memset(&resp, 0, sizeof resp); 809 memset(&resp, 0, sizeof resp);
638 resp.cq_handle = uobj->uobject.id; 810 resp.cq_handle = obj->uobject.id;
639 resp.cqe = cq->cqe; 811 resp.cqe = cq->cqe;
640 812
641 if (copy_to_user((void __user *) (unsigned long) cmd.response, 813 if (copy_to_user((void __user *) (unsigned long) cmd.response,
642 &resp, sizeof resp)) { 814 &resp, sizeof resp)) {
643 ret = -EFAULT; 815 ret = -EFAULT;
644 goto err_idr; 816 goto err_copy;
645 } 817 }
646 818
647 mutex_lock(&file->mutex); 819 mutex_lock(&file->mutex);
648 list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); 820 list_add_tail(&obj->uobject.list, &file->ucontext->cq_list);
649 mutex_unlock(&file->mutex); 821 mutex_unlock(&file->mutex);
650 822
651 mutex_unlock(&ib_uverbs_idr_mutex); 823 obj->uobject.live = 1;
824
825 up_write(&obj->uobject.mutex);
652 826
653 return in_len; 827 return in_len;
654 828
655err_idr: 829err_copy:
656 idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); 830 idr_remove_uobj(&ib_uverbs_cq_idr, &obj->uobject);
657 831
658err_up: 832
659 mutex_unlock(&ib_uverbs_idr_mutex); 833err_free:
660 ib_destroy_cq(cq); 834 ib_destroy_cq(cq);
661 835
662err: 836err_file:
663 if (ev_file) 837 if (ev_file)
664 ib_uverbs_release_ucq(file, ev_file, uobj); 838 ib_uverbs_release_ucq(file, ev_file, obj);
665 kfree(uobj); 839
840err:
841 put_uobj_write(&obj->uobject);
666 return ret; 842 return ret;
667} 843}
668 844
@@ -683,11 +859,9 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
683 (unsigned long) cmd.response + sizeof resp, 859 (unsigned long) cmd.response + sizeof resp,
684 in_len - sizeof cmd, out_len - sizeof resp); 860 in_len - sizeof cmd, out_len - sizeof resp);
685 861
686 mutex_lock(&ib_uverbs_idr_mutex); 862 cq = idr_read_cq(cmd.cq_handle, file->ucontext);
687 863 if (!cq)
688 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 864 return -EINVAL;
689 if (!cq || cq->uobject->context != file->ucontext || !cq->device->resize_cq)
690 goto out;
691 865
692 ret = cq->device->resize_cq(cq, cmd.cqe, &udata); 866 ret = cq->device->resize_cq(cq, cmd.cqe, &udata);
693 if (ret) 867 if (ret)
@@ -701,7 +875,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
701 ret = -EFAULT; 875 ret = -EFAULT;
702 876
703out: 877out:
704 mutex_unlock(&ib_uverbs_idr_mutex); 878 put_cq_read(cq);
705 879
706 return ret ? ret : in_len; 880 return ret ? ret : in_len;
707} 881}
@@ -712,6 +886,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
712{ 886{
713 struct ib_uverbs_poll_cq cmd; 887 struct ib_uverbs_poll_cq cmd;
714 struct ib_uverbs_poll_cq_resp *resp; 888 struct ib_uverbs_poll_cq_resp *resp;
889 struct ib_uobject *uobj;
715 struct ib_cq *cq; 890 struct ib_cq *cq;
716 struct ib_wc *wc; 891 struct ib_wc *wc;
717 int ret = 0; 892 int ret = 0;
@@ -732,15 +907,17 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
732 goto out_wc; 907 goto out_wc;
733 } 908 }
734 909
735 mutex_lock(&ib_uverbs_idr_mutex); 910 uobj = idr_read_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext);
736 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 911 if (!uobj) {
737 if (!cq || cq->uobject->context != file->ucontext) {
738 ret = -EINVAL; 912 ret = -EINVAL;
739 goto out; 913 goto out;
740 } 914 }
915 cq = uobj->object;
741 916
742 resp->count = ib_poll_cq(cq, cmd.ne, wc); 917 resp->count = ib_poll_cq(cq, cmd.ne, wc);
743 918
919 put_uobj_read(uobj);
920
744 for (i = 0; i < resp->count; i++) { 921 for (i = 0; i < resp->count; i++) {
745 resp->wc[i].wr_id = wc[i].wr_id; 922 resp->wc[i].wr_id = wc[i].wr_id;
746 resp->wc[i].status = wc[i].status; 923 resp->wc[i].status = wc[i].status;
@@ -762,7 +939,6 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
762 ret = -EFAULT; 939 ret = -EFAULT;
763 940
764out: 941out:
765 mutex_unlock(&ib_uverbs_idr_mutex);
766 kfree(resp); 942 kfree(resp);
767 943
768out_wc: 944out_wc:
@@ -775,22 +951,23 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
775 int out_len) 951 int out_len)
776{ 952{
777 struct ib_uverbs_req_notify_cq cmd; 953 struct ib_uverbs_req_notify_cq cmd;
954 struct ib_uobject *uobj;
778 struct ib_cq *cq; 955 struct ib_cq *cq;
779 int ret = -EINVAL;
780 956
781 if (copy_from_user(&cmd, buf, sizeof cmd)) 957 if (copy_from_user(&cmd, buf, sizeof cmd))
782 return -EFAULT; 958 return -EFAULT;
783 959
784 mutex_lock(&ib_uverbs_idr_mutex); 960 uobj = idr_read_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext);
785 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 961 if (!uobj)
786 if (cq && cq->uobject->context == file->ucontext) { 962 return -EINVAL;
787 ib_req_notify_cq(cq, cmd.solicited_only ? 963 cq = uobj->object;
788 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
789 ret = in_len;
790 }
791 mutex_unlock(&ib_uverbs_idr_mutex);
792 964
793 return ret; 965 ib_req_notify_cq(cq, cmd.solicited_only ?
966 IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
967
968 put_uobj_read(uobj);
969
970 return in_len;
794} 971}
795 972
796ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, 973ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
@@ -799,52 +976,50 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
799{ 976{
800 struct ib_uverbs_destroy_cq cmd; 977 struct ib_uverbs_destroy_cq cmd;
801 struct ib_uverbs_destroy_cq_resp resp; 978 struct ib_uverbs_destroy_cq_resp resp;
979 struct ib_uobject *uobj;
802 struct ib_cq *cq; 980 struct ib_cq *cq;
803 struct ib_ucq_object *uobj; 981 struct ib_ucq_object *obj;
804 struct ib_uverbs_event_file *ev_file; 982 struct ib_uverbs_event_file *ev_file;
805 u64 user_handle;
806 int ret = -EINVAL; 983 int ret = -EINVAL;
807 984
808 if (copy_from_user(&cmd, buf, sizeof cmd)) 985 if (copy_from_user(&cmd, buf, sizeof cmd))
809 return -EFAULT; 986 return -EFAULT;
810 987
811 memset(&resp, 0, sizeof resp); 988 uobj = idr_write_uobj(&ib_uverbs_cq_idr, cmd.cq_handle, file->ucontext);
812 989 if (!uobj)
813 mutex_lock(&ib_uverbs_idr_mutex); 990 return -EINVAL;
991 cq = uobj->object;
992 ev_file = cq->cq_context;
993 obj = container_of(cq->uobject, struct ib_ucq_object, uobject);
814 994
815 cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); 995 ret = ib_destroy_cq(cq);
816 if (!cq || cq->uobject->context != file->ucontext) 996 if (!ret)
817 goto out; 997 uobj->live = 0;
818 998
819 user_handle = cq->uobject->user_handle; 999 put_uobj_write(uobj);
820 uobj = container_of(cq->uobject, struct ib_ucq_object, uobject);
821 ev_file = cq->cq_context;
822 1000
823 ret = ib_destroy_cq(cq);
824 if (ret) 1001 if (ret)
825 goto out; 1002 return ret;
826 1003
827 idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); 1004 idr_remove_uobj(&ib_uverbs_cq_idr, uobj);
828 1005
829 mutex_lock(&file->mutex); 1006 mutex_lock(&file->mutex);
830 list_del(&uobj->uobject.list); 1007 list_del(&uobj->list);
831 mutex_unlock(&file->mutex); 1008 mutex_unlock(&file->mutex);
832 1009
833 ib_uverbs_release_ucq(file, ev_file, uobj); 1010 ib_uverbs_release_ucq(file, ev_file, obj);
834 1011
835 resp.comp_events_reported = uobj->comp_events_reported; 1012 memset(&resp, 0, sizeof resp);
836 resp.async_events_reported = uobj->async_events_reported; 1013 resp.comp_events_reported = obj->comp_events_reported;
1014 resp.async_events_reported = obj->async_events_reported;
837 1015
838 kfree(uobj); 1016 put_uobj(uobj);
839 1017
840 if (copy_to_user((void __user *) (unsigned long) cmd.response, 1018 if (copy_to_user((void __user *) (unsigned long) cmd.response,
841 &resp, sizeof resp)) 1019 &resp, sizeof resp))
842 ret = -EFAULT; 1020 return -EFAULT;
843
844out:
845 mutex_unlock(&ib_uverbs_idr_mutex);
846 1021
847 return ret ? ret : in_len; 1022 return in_len;
848} 1023}
849 1024
850ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, 1025ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
@@ -854,7 +1029,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
854 struct ib_uverbs_create_qp cmd; 1029 struct ib_uverbs_create_qp cmd;
855 struct ib_uverbs_create_qp_resp resp; 1030 struct ib_uverbs_create_qp_resp resp;
856 struct ib_udata udata; 1031 struct ib_udata udata;
857 struct ib_uqp_object *uobj; 1032 struct ib_uqp_object *obj;
858 struct ib_pd *pd; 1033 struct ib_pd *pd;
859 struct ib_cq *scq, *rcq; 1034 struct ib_cq *scq, *rcq;
860 struct ib_srq *srq; 1035 struct ib_srq *srq;
@@ -872,23 +1047,21 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
872 (unsigned long) cmd.response + sizeof resp, 1047 (unsigned long) cmd.response + sizeof resp,
873 in_len - sizeof cmd, out_len - sizeof resp); 1048 in_len - sizeof cmd, out_len - sizeof resp);
874 1049
875 uobj = kmalloc(sizeof *uobj, GFP_KERNEL); 1050 obj = kmalloc(sizeof *obj, GFP_KERNEL);
876 if (!uobj) 1051 if (!obj)
877 return -ENOMEM; 1052 return -ENOMEM;
878 1053
879 mutex_lock(&ib_uverbs_idr_mutex); 1054 init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext);
1055 down_write(&obj->uevent.uobject.mutex);
880 1056
881 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 1057 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
882 scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); 1058 scq = idr_read_cq(cmd.send_cq_handle, file->ucontext);
883 rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle); 1059 rcq = idr_read_cq(cmd.recv_cq_handle, file->ucontext);
884 srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL; 1060 srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
885 1061
886 if (!pd || pd->uobject->context != file->ucontext || 1062 if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) {
887 !scq || scq->uobject->context != file->ucontext ||
888 !rcq || rcq->uobject->context != file->ucontext ||
889 (cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) {
890 ret = -EINVAL; 1063 ret = -EINVAL;
891 goto err_up; 1064 goto err_put;
892 } 1065 }
893 1066
894 attr.event_handler = ib_uverbs_qp_event_handler; 1067 attr.event_handler = ib_uverbs_qp_event_handler;
@@ -905,16 +1078,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
905 attr.cap.max_recv_sge = cmd.max_recv_sge; 1078 attr.cap.max_recv_sge = cmd.max_recv_sge;
906 attr.cap.max_inline_data = cmd.max_inline_data; 1079 attr.cap.max_inline_data = cmd.max_inline_data;
907 1080
908 uobj->uevent.uobject.user_handle = cmd.user_handle; 1081 obj->uevent.events_reported = 0;
909 uobj->uevent.uobject.context = file->ucontext; 1082 INIT_LIST_HEAD(&obj->uevent.event_list);
910 uobj->uevent.events_reported = 0; 1083 INIT_LIST_HEAD(&obj->mcast_list);
911 INIT_LIST_HEAD(&uobj->uevent.event_list);
912 INIT_LIST_HEAD(&uobj->mcast_list);
913 1084
914 qp = pd->device->create_qp(pd, &attr, &udata); 1085 qp = pd->device->create_qp(pd, &attr, &udata);
915 if (IS_ERR(qp)) { 1086 if (IS_ERR(qp)) {
916 ret = PTR_ERR(qp); 1087 ret = PTR_ERR(qp);
917 goto err_up; 1088 goto err_put;
918 } 1089 }
919 1090
920 qp->device = pd->device; 1091 qp->device = pd->device;
@@ -922,7 +1093,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
922 qp->send_cq = attr.send_cq; 1093 qp->send_cq = attr.send_cq;
923 qp->recv_cq = attr.recv_cq; 1094 qp->recv_cq = attr.recv_cq;
924 qp->srq = attr.srq; 1095 qp->srq = attr.srq;
925 qp->uobject = &uobj->uevent.uobject; 1096 qp->uobject = &obj->uevent.uobject;
926 qp->event_handler = attr.event_handler; 1097 qp->event_handler = attr.event_handler;
927 qp->qp_context = attr.qp_context; 1098 qp->qp_context = attr.qp_context;
928 qp->qp_type = attr.qp_type; 1099 qp->qp_type = attr.qp_type;
@@ -932,14 +1103,14 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
932 if (attr.srq) 1103 if (attr.srq)
933 atomic_inc(&attr.srq->usecnt); 1104 atomic_inc(&attr.srq->usecnt);
934 1105
935 memset(&resp, 0, sizeof resp); 1106 obj->uevent.uobject.object = qp;
936 resp.qpn = qp->qp_num; 1107 ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
937
938 ret = idr_add_uobj(&ib_uverbs_qp_idr, qp, &uobj->uevent.uobject);
939 if (ret) 1108 if (ret)
940 goto err_destroy; 1109 goto err_destroy;
941 1110
942 resp.qp_handle = uobj->uevent.uobject.id; 1111 memset(&resp, 0, sizeof resp);
1112 resp.qpn = qp->qp_num;
1113 resp.qp_handle = obj->uevent.uobject.id;
943 resp.max_recv_sge = attr.cap.max_recv_sge; 1114 resp.max_recv_sge = attr.cap.max_recv_sge;
944 resp.max_send_sge = attr.cap.max_send_sge; 1115 resp.max_send_sge = attr.cap.max_send_sge;
945 resp.max_recv_wr = attr.cap.max_recv_wr; 1116 resp.max_recv_wr = attr.cap.max_recv_wr;
@@ -949,27 +1120,42 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
949 if (copy_to_user((void __user *) (unsigned long) cmd.response, 1120 if (copy_to_user((void __user *) (unsigned long) cmd.response,
950 &resp, sizeof resp)) { 1121 &resp, sizeof resp)) {
951 ret = -EFAULT; 1122 ret = -EFAULT;
952 goto err_idr; 1123 goto err_copy;
953 } 1124 }
954 1125
1126 put_pd_read(pd);
1127 put_cq_read(scq);
1128 put_cq_read(rcq);
1129 if (srq)
1130 put_srq_read(srq);
1131
955 mutex_lock(&file->mutex); 1132 mutex_lock(&file->mutex);
956 list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list); 1133 list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list);
957 mutex_unlock(&file->mutex); 1134 mutex_unlock(&file->mutex);
958 1135
959 mutex_unlock(&ib_uverbs_idr_mutex); 1136 obj->uevent.uobject.live = 1;
1137
1138 up_write(&obj->uevent.uobject.mutex);
960 1139
961 return in_len; 1140 return in_len;
962 1141
963err_idr: 1142err_copy:
964 idr_remove(&ib_uverbs_qp_idr, uobj->uevent.uobject.id); 1143 idr_remove_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject);
965 1144
966err_destroy: 1145err_destroy:
967 ib_destroy_qp(qp); 1146 ib_destroy_qp(qp);
968 1147
969err_up: 1148err_put:
970 mutex_unlock(&ib_uverbs_idr_mutex); 1149 if (pd)
971 1150 put_pd_read(pd);
972 kfree(uobj); 1151 if (scq)
1152 put_cq_read(scq);
1153 if (rcq)
1154 put_cq_read(rcq);
1155 if (srq)
1156 put_srq_read(srq);
1157
1158 put_uobj_write(&obj->uevent.uobject);
973 return ret; 1159 return ret;
974} 1160}
975 1161
@@ -994,15 +1180,15 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
994 goto out; 1180 goto out;
995 } 1181 }
996 1182
997 mutex_lock(&ib_uverbs_idr_mutex); 1183 qp = idr_read_qp(cmd.qp_handle, file->ucontext);
998 1184 if (!qp) {
999 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1000 if (qp && qp->uobject->context == file->ucontext)
1001 ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr);
1002 else
1003 ret = -EINVAL; 1185 ret = -EINVAL;
1186 goto out;
1187 }
1188
1189 ret = ib_query_qp(qp, attr, cmd.attr_mask, init_attr);
1004 1190
1005 mutex_unlock(&ib_uverbs_idr_mutex); 1191 put_qp_read(qp);
1006 1192
1007 if (ret) 1193 if (ret)
1008 goto out; 1194 goto out;
@@ -1089,10 +1275,8 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1089 if (!attr) 1275 if (!attr)
1090 return -ENOMEM; 1276 return -ENOMEM;
1091 1277
1092 mutex_lock(&ib_uverbs_idr_mutex); 1278 qp = idr_read_qp(cmd.qp_handle, file->ucontext);
1093 1279 if (!qp) {
1094 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1095 if (!qp || qp->uobject->context != file->ucontext) {
1096 ret = -EINVAL; 1280 ret = -EINVAL;
1097 goto out; 1281 goto out;
1098 } 1282 }
@@ -1144,13 +1328,15 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1144 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; 1328 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
1145 1329
1146 ret = ib_modify_qp(qp, attr, cmd.attr_mask); 1330 ret = ib_modify_qp(qp, attr, cmd.attr_mask);
1331
1332 put_qp_read(qp);
1333
1147 if (ret) 1334 if (ret)
1148 goto out; 1335 goto out;
1149 1336
1150 ret = in_len; 1337 ret = in_len;
1151 1338
1152out: 1339out:
1153 mutex_unlock(&ib_uverbs_idr_mutex);
1154 kfree(attr); 1340 kfree(attr);
1155 1341
1156 return ret; 1342 return ret;
@@ -1162,8 +1348,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1162{ 1348{
1163 struct ib_uverbs_destroy_qp cmd; 1349 struct ib_uverbs_destroy_qp cmd;
1164 struct ib_uverbs_destroy_qp_resp resp; 1350 struct ib_uverbs_destroy_qp_resp resp;
1351 struct ib_uobject *uobj;
1165 struct ib_qp *qp; 1352 struct ib_qp *qp;
1166 struct ib_uqp_object *uobj; 1353 struct ib_uqp_object *obj;
1167 int ret = -EINVAL; 1354 int ret = -EINVAL;
1168 1355
1169 if (copy_from_user(&cmd, buf, sizeof cmd)) 1356 if (copy_from_user(&cmd, buf, sizeof cmd))
@@ -1171,43 +1358,43 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
1171 1358
1172 memset(&resp, 0, sizeof resp); 1359 memset(&resp, 0, sizeof resp);
1173 1360
1174 mutex_lock(&ib_uverbs_idr_mutex); 1361 uobj = idr_write_uobj(&ib_uverbs_qp_idr, cmd.qp_handle, file->ucontext);
1175 1362 if (!uobj)
1176 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1363 return -EINVAL;
1177 if (!qp || qp->uobject->context != file->ucontext) 1364 qp = uobj->object;
1178 goto out; 1365 obj = container_of(uobj, struct ib_uqp_object, uevent.uobject);
1179
1180 uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
1181 1366
1182 if (!list_empty(&uobj->mcast_list)) { 1367 if (!list_empty(&obj->mcast_list)) {
1183 ret = -EBUSY; 1368 put_uobj_write(uobj);
1184 goto out; 1369 return -EBUSY;
1185 } 1370 }
1186 1371
1187 ret = ib_destroy_qp(qp); 1372 ret = ib_destroy_qp(qp);
1373 if (!ret)
1374 uobj->live = 0;
1375
1376 put_uobj_write(uobj);
1377
1188 if (ret) 1378 if (ret)
1189 goto out; 1379 return ret;
1190 1380
1191 idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); 1381 idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
1192 1382
1193 mutex_lock(&file->mutex); 1383 mutex_lock(&file->mutex);
1194 list_del(&uobj->uevent.uobject.list); 1384 list_del(&uobj->list);
1195 mutex_unlock(&file->mutex); 1385 mutex_unlock(&file->mutex);
1196 1386
1197 ib_uverbs_release_uevent(file, &uobj->uevent); 1387 ib_uverbs_release_uevent(file, &obj->uevent);
1198 1388
1199 resp.events_reported = uobj->uevent.events_reported; 1389 resp.events_reported = obj->uevent.events_reported;
1200 1390
1201 kfree(uobj); 1391 put_uobj(uobj);
1202 1392
1203 if (copy_to_user((void __user *) (unsigned long) cmd.response, 1393 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1204 &resp, sizeof resp)) 1394 &resp, sizeof resp))
1205 ret = -EFAULT; 1395 return -EFAULT;
1206
1207out:
1208 mutex_unlock(&ib_uverbs_idr_mutex);
1209 1396
1210 return ret ? ret : in_len; 1397 return in_len;
1211} 1398}
1212 1399
1213ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, 1400ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
@@ -1220,6 +1407,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1220 struct ib_send_wr *wr = NULL, *last, *next, *bad_wr; 1407 struct ib_send_wr *wr = NULL, *last, *next, *bad_wr;
1221 struct ib_qp *qp; 1408 struct ib_qp *qp;
1222 int i, sg_ind; 1409 int i, sg_ind;
1410 int is_ud;
1223 ssize_t ret = -EINVAL; 1411 ssize_t ret = -EINVAL;
1224 1412
1225 if (copy_from_user(&cmd, buf, sizeof cmd)) 1413 if (copy_from_user(&cmd, buf, sizeof cmd))
@@ -1236,12 +1424,11 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1236 if (!user_wr) 1424 if (!user_wr)
1237 return -ENOMEM; 1425 return -ENOMEM;
1238 1426
1239 mutex_lock(&ib_uverbs_idr_mutex); 1427 qp = idr_read_qp(cmd.qp_handle, file->ucontext);
1240 1428 if (!qp)
1241 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1242 if (!qp || qp->uobject->context != file->ucontext)
1243 goto out; 1429 goto out;
1244 1430
1431 is_ud = qp->qp_type == IB_QPT_UD;
1245 sg_ind = 0; 1432 sg_ind = 0;
1246 last = NULL; 1433 last = NULL;
1247 for (i = 0; i < cmd.wr_count; ++i) { 1434 for (i = 0; i < cmd.wr_count; ++i) {
@@ -1249,12 +1436,12 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1249 buf + sizeof cmd + i * cmd.wqe_size, 1436 buf + sizeof cmd + i * cmd.wqe_size,
1250 cmd.wqe_size)) { 1437 cmd.wqe_size)) {
1251 ret = -EFAULT; 1438 ret = -EFAULT;
1252 goto out; 1439 goto out_put;
1253 } 1440 }
1254 1441
1255 if (user_wr->num_sge + sg_ind > cmd.sge_count) { 1442 if (user_wr->num_sge + sg_ind > cmd.sge_count) {
1256 ret = -EINVAL; 1443 ret = -EINVAL;
1257 goto out; 1444 goto out_put;
1258 } 1445 }
1259 1446
1260 next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) + 1447 next = kmalloc(ALIGN(sizeof *next, sizeof (struct ib_sge)) +
@@ -1262,7 +1449,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1262 GFP_KERNEL); 1449 GFP_KERNEL);
1263 if (!next) { 1450 if (!next) {
1264 ret = -ENOMEM; 1451 ret = -ENOMEM;
1265 goto out; 1452 goto out_put;
1266 } 1453 }
1267 1454
1268 if (!last) 1455 if (!last)
@@ -1278,12 +1465,12 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1278 next->send_flags = user_wr->send_flags; 1465 next->send_flags = user_wr->send_flags;
1279 next->imm_data = (__be32 __force) user_wr->imm_data; 1466 next->imm_data = (__be32 __force) user_wr->imm_data;
1280 1467
1281 if (qp->qp_type == IB_QPT_UD) { 1468 if (is_ud) {
1282 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, 1469 next->wr.ud.ah = idr_read_ah(user_wr->wr.ud.ah,
1283 user_wr->wr.ud.ah); 1470 file->ucontext);
1284 if (!next->wr.ud.ah) { 1471 if (!next->wr.ud.ah) {
1285 ret = -EINVAL; 1472 ret = -EINVAL;
1286 goto out; 1473 goto out_put;
1287 } 1474 }
1288 next->wr.ud.remote_qpn = user_wr->wr.ud.remote_qpn; 1475 next->wr.ud.remote_qpn = user_wr->wr.ud.remote_qpn;
1289 next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey; 1476 next->wr.ud.remote_qkey = user_wr->wr.ud.remote_qkey;
@@ -1320,7 +1507,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1320 sg_ind * sizeof (struct ib_sge), 1507 sg_ind * sizeof (struct ib_sge),
1321 next->num_sge * sizeof (struct ib_sge))) { 1508 next->num_sge * sizeof (struct ib_sge))) {
1322 ret = -EFAULT; 1509 ret = -EFAULT;
1323 goto out; 1510 goto out_put;
1324 } 1511 }
1325 sg_ind += next->num_sge; 1512 sg_ind += next->num_sge;
1326 } else 1513 } else
@@ -1340,10 +1527,13 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1340 &resp, sizeof resp)) 1527 &resp, sizeof resp))
1341 ret = -EFAULT; 1528 ret = -EFAULT;
1342 1529
1343out: 1530out_put:
1344 mutex_unlock(&ib_uverbs_idr_mutex); 1531 put_qp_read(qp);
1345 1532
1533out:
1346 while (wr) { 1534 while (wr) {
1535 if (is_ud && wr->wr.ud.ah)
1536 put_ah_read(wr->wr.ud.ah);
1347 next = wr->next; 1537 next = wr->next;
1348 kfree(wr); 1538 kfree(wr);
1349 wr = next; 1539 wr = next;
@@ -1458,14 +1648,15 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
1458 if (IS_ERR(wr)) 1648 if (IS_ERR(wr))
1459 return PTR_ERR(wr); 1649 return PTR_ERR(wr);
1460 1650
1461 mutex_lock(&ib_uverbs_idr_mutex); 1651 qp = idr_read_qp(cmd.qp_handle, file->ucontext);
1462 1652 if (!qp)
1463 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
1464 if (!qp || qp->uobject->context != file->ucontext)
1465 goto out; 1653 goto out;
1466 1654
1467 resp.bad_wr = 0; 1655 resp.bad_wr = 0;
1468 ret = qp->device->post_recv(qp, wr, &bad_wr); 1656 ret = qp->device->post_recv(qp, wr, &bad_wr);
1657
1658 put_qp_read(qp);
1659
1469 if (ret) 1660 if (ret)
1470 for (next = wr; next; next = next->next) { 1661 for (next = wr; next; next = next->next) {
1471 ++resp.bad_wr; 1662 ++resp.bad_wr;
@@ -1479,8 +1670,6 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
1479 ret = -EFAULT; 1670 ret = -EFAULT;
1480 1671
1481out: 1672out:
1482 mutex_unlock(&ib_uverbs_idr_mutex);
1483
1484 while (wr) { 1673 while (wr) {
1485 next = wr->next; 1674 next = wr->next;
1486 kfree(wr); 1675 kfree(wr);
@@ -1509,14 +1698,15 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
1509 if (IS_ERR(wr)) 1698 if (IS_ERR(wr))
1510 return PTR_ERR(wr); 1699 return PTR_ERR(wr);
1511 1700
1512 mutex_lock(&ib_uverbs_idr_mutex); 1701 srq = idr_read_srq(cmd.srq_handle, file->ucontext);
1513 1702 if (!srq)
1514 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1515 if (!srq || srq->uobject->context != file->ucontext)
1516 goto out; 1703 goto out;
1517 1704
1518 resp.bad_wr = 0; 1705 resp.bad_wr = 0;
1519 ret = srq->device->post_srq_recv(srq, wr, &bad_wr); 1706 ret = srq->device->post_srq_recv(srq, wr, &bad_wr);
1707
1708 put_srq_read(srq);
1709
1520 if (ret) 1710 if (ret)
1521 for (next = wr; next; next = next->next) { 1711 for (next = wr; next; next = next->next) {
1522 ++resp.bad_wr; 1712 ++resp.bad_wr;
@@ -1530,8 +1720,6 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
1530 ret = -EFAULT; 1720 ret = -EFAULT;
1531 1721
1532out: 1722out:
1533 mutex_unlock(&ib_uverbs_idr_mutex);
1534
1535 while (wr) { 1723 while (wr) {
1536 next = wr->next; 1724 next = wr->next;
1537 kfree(wr); 1725 kfree(wr);
@@ -1563,17 +1751,15 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
1563 if (!uobj) 1751 if (!uobj)
1564 return -ENOMEM; 1752 return -ENOMEM;
1565 1753
1566 mutex_lock(&ib_uverbs_idr_mutex); 1754 init_uobj(uobj, cmd.user_handle, file->ucontext);
1755 down_write(&uobj->mutex);
1567 1756
1568 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 1757 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1569 if (!pd || pd->uobject->context != file->ucontext) { 1758 if (!pd) {
1570 ret = -EINVAL; 1759 ret = -EINVAL;
1571 goto err_up; 1760 goto err;
1572 } 1761 }
1573 1762
1574 uobj->user_handle = cmd.user_handle;
1575 uobj->context = file->ucontext;
1576
1577 attr.dlid = cmd.attr.dlid; 1763 attr.dlid = cmd.attr.dlid;
1578 attr.sl = cmd.attr.sl; 1764 attr.sl = cmd.attr.sl;
1579 attr.src_path_bits = cmd.attr.src_path_bits; 1765 attr.src_path_bits = cmd.attr.src_path_bits;
@@ -1589,12 +1775,13 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
1589 ah = ib_create_ah(pd, &attr); 1775 ah = ib_create_ah(pd, &attr);
1590 if (IS_ERR(ah)) { 1776 if (IS_ERR(ah)) {
1591 ret = PTR_ERR(ah); 1777 ret = PTR_ERR(ah);
1592 goto err_up; 1778 goto err;
1593 } 1779 }
1594 1780
1595 ah->uobject = uobj; 1781 ah->uobject = uobj;
1782 uobj->object = ah;
1596 1783
1597 ret = idr_add_uobj(&ib_uverbs_ah_idr, ah, uobj); 1784 ret = idr_add_uobj(&ib_uverbs_ah_idr, uobj);
1598 if (ret) 1785 if (ret)
1599 goto err_destroy; 1786 goto err_destroy;
1600 1787
@@ -1603,27 +1790,29 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
1603 if (copy_to_user((void __user *) (unsigned long) cmd.response, 1790 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1604 &resp, sizeof resp)) { 1791 &resp, sizeof resp)) {
1605 ret = -EFAULT; 1792 ret = -EFAULT;
1606 goto err_idr; 1793 goto err_copy;
1607 } 1794 }
1608 1795
1796 put_pd_read(pd);
1797
1609 mutex_lock(&file->mutex); 1798 mutex_lock(&file->mutex);
1610 list_add_tail(&uobj->list, &file->ucontext->ah_list); 1799 list_add_tail(&uobj->list, &file->ucontext->ah_list);
1611 mutex_unlock(&file->mutex); 1800 mutex_unlock(&file->mutex);
1612 1801
1613 mutex_unlock(&ib_uverbs_idr_mutex); 1802 uobj->live = 1;
1803
1804 up_write(&uobj->mutex);
1614 1805
1615 return in_len; 1806 return in_len;
1616 1807
1617err_idr: 1808err_copy:
1618 idr_remove(&ib_uverbs_ah_idr, uobj->id); 1809 idr_remove_uobj(&ib_uverbs_ah_idr, uobj);
1619 1810
1620err_destroy: 1811err_destroy:
1621 ib_destroy_ah(ah); 1812 ib_destroy_ah(ah);
1622 1813
1623err_up: 1814err:
1624 mutex_unlock(&ib_uverbs_idr_mutex); 1815 put_uobj_write(uobj);
1625
1626 kfree(uobj);
1627 return ret; 1816 return ret;
1628} 1817}
1629 1818
@@ -1633,35 +1822,34 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
1633 struct ib_uverbs_destroy_ah cmd; 1822 struct ib_uverbs_destroy_ah cmd;
1634 struct ib_ah *ah; 1823 struct ib_ah *ah;
1635 struct ib_uobject *uobj; 1824 struct ib_uobject *uobj;
1636 int ret = -EINVAL; 1825 int ret;
1637 1826
1638 if (copy_from_user(&cmd, buf, sizeof cmd)) 1827 if (copy_from_user(&cmd, buf, sizeof cmd))
1639 return -EFAULT; 1828 return -EFAULT;
1640 1829
1641 mutex_lock(&ib_uverbs_idr_mutex); 1830 uobj = idr_write_uobj(&ib_uverbs_ah_idr, cmd.ah_handle, file->ucontext);
1831 if (!uobj)
1832 return -EINVAL;
1833 ah = uobj->object;
1642 1834
1643 ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle); 1835 ret = ib_destroy_ah(ah);
1644 if (!ah || ah->uobject->context != file->ucontext) 1836 if (!ret)
1645 goto out; 1837 uobj->live = 0;
1646 1838
1647 uobj = ah->uobject; 1839 put_uobj_write(uobj);
1648 1840
1649 ret = ib_destroy_ah(ah);
1650 if (ret) 1841 if (ret)
1651 goto out; 1842 return ret;
1652 1843
1653 idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle); 1844 idr_remove_uobj(&ib_uverbs_ah_idr, uobj);
1654 1845
1655 mutex_lock(&file->mutex); 1846 mutex_lock(&file->mutex);
1656 list_del(&uobj->list); 1847 list_del(&uobj->list);
1657 mutex_unlock(&file->mutex); 1848 mutex_unlock(&file->mutex);
1658 1849
1659 kfree(uobj); 1850 put_uobj(uobj);
1660 1851
1661out: 1852 return in_len;
1662 mutex_unlock(&ib_uverbs_idr_mutex);
1663
1664 return ret ? ret : in_len;
1665} 1853}
1666 1854
1667ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, 1855ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
@@ -1670,47 +1858,43 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
1670{ 1858{
1671 struct ib_uverbs_attach_mcast cmd; 1859 struct ib_uverbs_attach_mcast cmd;
1672 struct ib_qp *qp; 1860 struct ib_qp *qp;
1673 struct ib_uqp_object *uobj; 1861 struct ib_uqp_object *obj;
1674 struct ib_uverbs_mcast_entry *mcast; 1862 struct ib_uverbs_mcast_entry *mcast;
1675 int ret = -EINVAL; 1863 int ret;
1676 1864
1677 if (copy_from_user(&cmd, buf, sizeof cmd)) 1865 if (copy_from_user(&cmd, buf, sizeof cmd))
1678 return -EFAULT; 1866 return -EFAULT;
1679 1867
1680 mutex_lock(&ib_uverbs_idr_mutex); 1868 qp = idr_read_qp(cmd.qp_handle, file->ucontext);
1681 1869 if (!qp)
1682 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1870 return -EINVAL;
1683 if (!qp || qp->uobject->context != file->ucontext)
1684 goto out;
1685 1871
1686 uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); 1872 obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
1687 1873
1688 list_for_each_entry(mcast, &uobj->mcast_list, list) 1874 list_for_each_entry(mcast, &obj->mcast_list, list)
1689 if (cmd.mlid == mcast->lid && 1875 if (cmd.mlid == mcast->lid &&
1690 !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { 1876 !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
1691 ret = 0; 1877 ret = 0;
1692 goto out; 1878 goto out_put;
1693 } 1879 }
1694 1880
1695 mcast = kmalloc(sizeof *mcast, GFP_KERNEL); 1881 mcast = kmalloc(sizeof *mcast, GFP_KERNEL);
1696 if (!mcast) { 1882 if (!mcast) {
1697 ret = -ENOMEM; 1883 ret = -ENOMEM;
1698 goto out; 1884 goto out_put;
1699 } 1885 }
1700 1886
1701 mcast->lid = cmd.mlid; 1887 mcast->lid = cmd.mlid;
1702 memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw); 1888 memcpy(mcast->gid.raw, cmd.gid, sizeof mcast->gid.raw);
1703 1889
1704 ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid); 1890 ret = ib_attach_mcast(qp, &mcast->gid, cmd.mlid);
1705 if (!ret) { 1891 if (!ret)
1706 uobj = container_of(qp->uobject, struct ib_uqp_object, 1892 list_add_tail(&mcast->list, &obj->mcast_list);
1707 uevent.uobject); 1893 else
1708 list_add_tail(&mcast->list, &uobj->mcast_list);
1709 } else
1710 kfree(mcast); 1894 kfree(mcast);
1711 1895
1712out: 1896out_put:
1713 mutex_unlock(&ib_uverbs_idr_mutex); 1897 put_qp_read(qp);
1714 1898
1715 return ret ? ret : in_len; 1899 return ret ? ret : in_len;
1716} 1900}
@@ -1720,7 +1904,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1720 int out_len) 1904 int out_len)
1721{ 1905{
1722 struct ib_uverbs_detach_mcast cmd; 1906 struct ib_uverbs_detach_mcast cmd;
1723 struct ib_uqp_object *uobj; 1907 struct ib_uqp_object *obj;
1724 struct ib_qp *qp; 1908 struct ib_qp *qp;
1725 struct ib_uverbs_mcast_entry *mcast; 1909 struct ib_uverbs_mcast_entry *mcast;
1726 int ret = -EINVAL; 1910 int ret = -EINVAL;
@@ -1728,19 +1912,17 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1728 if (copy_from_user(&cmd, buf, sizeof cmd)) 1912 if (copy_from_user(&cmd, buf, sizeof cmd))
1729 return -EFAULT; 1913 return -EFAULT;
1730 1914
1731 mutex_lock(&ib_uverbs_idr_mutex); 1915 qp = idr_read_qp(cmd.qp_handle, file->ucontext);
1732 1916 if (!qp)
1733 qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); 1917 return -EINVAL;
1734 if (!qp || qp->uobject->context != file->ucontext)
1735 goto out;
1736 1918
1737 ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid); 1919 ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
1738 if (ret) 1920 if (ret)
1739 goto out; 1921 goto out_put;
1740 1922
1741 uobj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject); 1923 obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
1742 1924
1743 list_for_each_entry(mcast, &uobj->mcast_list, list) 1925 list_for_each_entry(mcast, &obj->mcast_list, list)
1744 if (cmd.mlid == mcast->lid && 1926 if (cmd.mlid == mcast->lid &&
1745 !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) { 1927 !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
1746 list_del(&mcast->list); 1928 list_del(&mcast->list);
@@ -1748,8 +1930,8 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1748 break; 1930 break;
1749 } 1931 }
1750 1932
1751out: 1933out_put:
1752 mutex_unlock(&ib_uverbs_idr_mutex); 1934 put_qp_read(qp);
1753 1935
1754 return ret ? ret : in_len; 1936 return ret ? ret : in_len;
1755} 1937}
@@ -1761,7 +1943,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1761 struct ib_uverbs_create_srq cmd; 1943 struct ib_uverbs_create_srq cmd;
1762 struct ib_uverbs_create_srq_resp resp; 1944 struct ib_uverbs_create_srq_resp resp;
1763 struct ib_udata udata; 1945 struct ib_udata udata;
1764 struct ib_uevent_object *uobj; 1946 struct ib_uevent_object *obj;
1765 struct ib_pd *pd; 1947 struct ib_pd *pd;
1766 struct ib_srq *srq; 1948 struct ib_srq *srq;
1767 struct ib_srq_init_attr attr; 1949 struct ib_srq_init_attr attr;
@@ -1777,17 +1959,17 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1777 (unsigned long) cmd.response + sizeof resp, 1959 (unsigned long) cmd.response + sizeof resp,
1778 in_len - sizeof cmd, out_len - sizeof resp); 1960 in_len - sizeof cmd, out_len - sizeof resp);
1779 1961
1780 uobj = kmalloc(sizeof *uobj, GFP_KERNEL); 1962 obj = kmalloc(sizeof *obj, GFP_KERNEL);
1781 if (!uobj) 1963 if (!obj)
1782 return -ENOMEM; 1964 return -ENOMEM;
1783 1965
1784 mutex_lock(&ib_uverbs_idr_mutex); 1966 init_uobj(&obj->uobject, 0, file->ucontext);
1785 1967 down_write(&obj->uobject.mutex);
1786 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1787 1968
1788 if (!pd || pd->uobject->context != file->ucontext) { 1969 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1970 if (!pd) {
1789 ret = -EINVAL; 1971 ret = -EINVAL;
1790 goto err_up; 1972 goto err;
1791 } 1973 }
1792 1974
1793 attr.event_handler = ib_uverbs_srq_event_handler; 1975 attr.event_handler = ib_uverbs_srq_event_handler;
@@ -1796,59 +1978,59 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1796 attr.attr.max_sge = cmd.max_sge; 1978 attr.attr.max_sge = cmd.max_sge;
1797 attr.attr.srq_limit = cmd.srq_limit; 1979 attr.attr.srq_limit = cmd.srq_limit;
1798 1980
1799 uobj->uobject.user_handle = cmd.user_handle; 1981 obj->events_reported = 0;
1800 uobj->uobject.context = file->ucontext; 1982 INIT_LIST_HEAD(&obj->event_list);
1801 uobj->events_reported = 0;
1802 INIT_LIST_HEAD(&uobj->event_list);
1803 1983
1804 srq = pd->device->create_srq(pd, &attr, &udata); 1984 srq = pd->device->create_srq(pd, &attr, &udata);
1805 if (IS_ERR(srq)) { 1985 if (IS_ERR(srq)) {
1806 ret = PTR_ERR(srq); 1986 ret = PTR_ERR(srq);
1807 goto err_up; 1987 goto err;
1808 } 1988 }
1809 1989
1810 srq->device = pd->device; 1990 srq->device = pd->device;
1811 srq->pd = pd; 1991 srq->pd = pd;
1812 srq->uobject = &uobj->uobject; 1992 srq->uobject = &obj->uobject;
1813 srq->event_handler = attr.event_handler; 1993 srq->event_handler = attr.event_handler;
1814 srq->srq_context = attr.srq_context; 1994 srq->srq_context = attr.srq_context;
1815 atomic_inc(&pd->usecnt); 1995 atomic_inc(&pd->usecnt);
1816 atomic_set(&srq->usecnt, 0); 1996 atomic_set(&srq->usecnt, 0);
1817 1997
1818 memset(&resp, 0, sizeof resp); 1998 obj->uobject.object = srq;
1819 1999 ret = idr_add_uobj(&ib_uverbs_srq_idr, &obj->uobject);
1820 ret = idr_add_uobj(&ib_uverbs_srq_idr, srq, &uobj->uobject);
1821 if (ret) 2000 if (ret)
1822 goto err_destroy; 2001 goto err_destroy;
1823 2002
1824 resp.srq_handle = uobj->uobject.id; 2003 memset(&resp, 0, sizeof resp);
2004 resp.srq_handle = obj->uobject.id;
1825 resp.max_wr = attr.attr.max_wr; 2005 resp.max_wr = attr.attr.max_wr;
1826 resp.max_sge = attr.attr.max_sge; 2006 resp.max_sge = attr.attr.max_sge;
1827 2007
1828 if (copy_to_user((void __user *) (unsigned long) cmd.response, 2008 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1829 &resp, sizeof resp)) { 2009 &resp, sizeof resp)) {
1830 ret = -EFAULT; 2010 ret = -EFAULT;
1831 goto err_idr; 2011 goto err_copy;
1832 } 2012 }
1833 2013
2014 put_pd_read(pd);
2015
1834 mutex_lock(&file->mutex); 2016 mutex_lock(&file->mutex);
1835 list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); 2017 list_add_tail(&obj->uobject.list, &file->ucontext->srq_list);
1836 mutex_unlock(&file->mutex); 2018 mutex_unlock(&file->mutex);
1837 2019
1838 mutex_unlock(&ib_uverbs_idr_mutex); 2020 obj->uobject.live = 1;
2021
2022 up_write(&obj->uobject.mutex);
1839 2023
1840 return in_len; 2024 return in_len;
1841 2025
1842err_idr: 2026err_copy:
1843 idr_remove(&ib_uverbs_srq_idr, uobj->uobject.id); 2027 idr_remove_uobj(&ib_uverbs_srq_idr, &obj->uobject);
1844 2028
1845err_destroy: 2029err_destroy:
1846 ib_destroy_srq(srq); 2030 ib_destroy_srq(srq);
1847 2031
1848err_up: 2032err:
1849 mutex_unlock(&ib_uverbs_idr_mutex); 2033 put_uobj_write(&obj->uobject);
1850
1851 kfree(uobj);
1852 return ret; 2034 return ret;
1853} 2035}
1854 2036
@@ -1864,21 +2046,16 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1864 if (copy_from_user(&cmd, buf, sizeof cmd)) 2046 if (copy_from_user(&cmd, buf, sizeof cmd))
1865 return -EFAULT; 2047 return -EFAULT;
1866 2048
1867 mutex_lock(&ib_uverbs_idr_mutex); 2049 srq = idr_read_srq(cmd.srq_handle, file->ucontext);
1868 2050 if (!srq)
1869 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); 2051 return -EINVAL;
1870 if (!srq || srq->uobject->context != file->ucontext) {
1871 ret = -EINVAL;
1872 goto out;
1873 }
1874 2052
1875 attr.max_wr = cmd.max_wr; 2053 attr.max_wr = cmd.max_wr;
1876 attr.srq_limit = cmd.srq_limit; 2054 attr.srq_limit = cmd.srq_limit;
1877 2055
1878 ret = ib_modify_srq(srq, &attr, cmd.attr_mask); 2056 ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
1879 2057
1880out: 2058 put_srq_read(srq);
1881 mutex_unlock(&ib_uverbs_idr_mutex);
1882 2059
1883 return ret ? ret : in_len; 2060 return ret ? ret : in_len;
1884} 2061}
@@ -1899,18 +2076,16 @@ ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,
1899 if (copy_from_user(&cmd, buf, sizeof cmd)) 2076 if (copy_from_user(&cmd, buf, sizeof cmd))
1900 return -EFAULT; 2077 return -EFAULT;
1901 2078
1902 mutex_lock(&ib_uverbs_idr_mutex); 2079 srq = idr_read_srq(cmd.srq_handle, file->ucontext);
2080 if (!srq)
2081 return -EINVAL;
1903 2082
1904 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); 2083 ret = ib_query_srq(srq, &attr);
1905 if (srq && srq->uobject->context == file->ucontext)
1906 ret = ib_query_srq(srq, &attr);
1907 else
1908 ret = -EINVAL;
1909 2084
1910 mutex_unlock(&ib_uverbs_idr_mutex); 2085 put_srq_read(srq);
1911 2086
1912 if (ret) 2087 if (ret)
1913 goto out; 2088 return ret;
1914 2089
1915 memset(&resp, 0, sizeof resp); 2090 memset(&resp, 0, sizeof resp);
1916 2091
@@ -1920,10 +2095,9 @@ ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,
1920 2095
1921 if (copy_to_user((void __user *) (unsigned long) cmd.response, 2096 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1922 &resp, sizeof resp)) 2097 &resp, sizeof resp))
1923 ret = -EFAULT; 2098 return -EFAULT;
1924 2099
1925out: 2100 return in_len;
1926 return ret ? ret : in_len;
1927} 2101}
1928 2102
1929ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, 2103ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
@@ -1932,45 +2106,45 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1932{ 2106{
1933 struct ib_uverbs_destroy_srq cmd; 2107 struct ib_uverbs_destroy_srq cmd;
1934 struct ib_uverbs_destroy_srq_resp resp; 2108 struct ib_uverbs_destroy_srq_resp resp;
2109 struct ib_uobject *uobj;
1935 struct ib_srq *srq; 2110 struct ib_srq *srq;
1936 struct ib_uevent_object *uobj; 2111 struct ib_uevent_object *obj;
1937 int ret = -EINVAL; 2112 int ret = -EINVAL;
1938 2113
1939 if (copy_from_user(&cmd, buf, sizeof cmd)) 2114 if (copy_from_user(&cmd, buf, sizeof cmd))
1940 return -EFAULT; 2115 return -EFAULT;
1941 2116
1942 mutex_lock(&ib_uverbs_idr_mutex); 2117 uobj = idr_write_uobj(&ib_uverbs_srq_idr, cmd.srq_handle, file->ucontext);
1943 2118 if (!uobj)
1944 memset(&resp, 0, sizeof resp); 2119 return -EINVAL;
2120 srq = uobj->object;
2121 obj = container_of(uobj, struct ib_uevent_object, uobject);
1945 2122
1946 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); 2123 ret = ib_destroy_srq(srq);
1947 if (!srq || srq->uobject->context != file->ucontext) 2124 if (!ret)
1948 goto out; 2125 uobj->live = 0;
1949 2126
1950 uobj = container_of(srq->uobject, struct ib_uevent_object, uobject); 2127 put_uobj_write(uobj);
1951 2128
1952 ret = ib_destroy_srq(srq);
1953 if (ret) 2129 if (ret)
1954 goto out; 2130 return ret;
1955 2131
1956 idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); 2132 idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
1957 2133
1958 mutex_lock(&file->mutex); 2134 mutex_lock(&file->mutex);
1959 list_del(&uobj->uobject.list); 2135 list_del(&uobj->list);
1960 mutex_unlock(&file->mutex); 2136 mutex_unlock(&file->mutex);
1961 2137
1962 ib_uverbs_release_uevent(file, uobj); 2138 ib_uverbs_release_uevent(file, obj);
1963 2139
1964 resp.events_reported = uobj->events_reported; 2140 memset(&resp, 0, sizeof resp);
2141 resp.events_reported = obj->events_reported;
1965 2142
1966 kfree(uobj); 2143 put_uobj(uobj);
1967 2144
1968 if (copy_to_user((void __user *) (unsigned long) cmd.response, 2145 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1969 &resp, sizeof resp)) 2146 &resp, sizeof resp))
1970 ret = -EFAULT; 2147 ret = -EFAULT;
1971 2148
1972out:
1973 mutex_unlock(&ib_uverbs_idr_mutex);
1974
1975 return ret ? ret : in_len; 2149 return ret ? ret : in_len;
1976} 2150}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index ff092a0a94da..5ec2d49e9bb6 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -66,7 +66,7 @@ enum {
66 66
67static struct class *uverbs_class; 67static struct class *uverbs_class;
68 68
69DEFINE_MUTEX(ib_uverbs_idr_mutex); 69DEFINE_SPINLOCK(ib_uverbs_idr_lock);
70DEFINE_IDR(ib_uverbs_pd_idr); 70DEFINE_IDR(ib_uverbs_pd_idr);
71DEFINE_IDR(ib_uverbs_mr_idr); 71DEFINE_IDR(ib_uverbs_mr_idr);
72DEFINE_IDR(ib_uverbs_mw_idr); 72DEFINE_IDR(ib_uverbs_mw_idr);
@@ -183,21 +183,21 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
183 if (!context) 183 if (!context)
184 return 0; 184 return 0;
185 185
186 mutex_lock(&ib_uverbs_idr_mutex);
187
188 list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { 186 list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) {
189 struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); 187 struct ib_ah *ah = uobj->object;
190 idr_remove(&ib_uverbs_ah_idr, uobj->id); 188
189 idr_remove_uobj(&ib_uverbs_ah_idr, uobj);
191 ib_destroy_ah(ah); 190 ib_destroy_ah(ah);
192 list_del(&uobj->list); 191 list_del(&uobj->list);
193 kfree(uobj); 192 kfree(uobj);
194 } 193 }
195 194
196 list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) { 195 list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
197 struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id); 196 struct ib_qp *qp = uobj->object;
198 struct ib_uqp_object *uqp = 197 struct ib_uqp_object *uqp =
199 container_of(uobj, struct ib_uqp_object, uevent.uobject); 198 container_of(uobj, struct ib_uqp_object, uevent.uobject);
200 idr_remove(&ib_uverbs_qp_idr, uobj->id); 199
200 idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
201 ib_uverbs_detach_umcast(qp, uqp); 201 ib_uverbs_detach_umcast(qp, uqp);
202 ib_destroy_qp(qp); 202 ib_destroy_qp(qp);
203 list_del(&uobj->list); 203 list_del(&uobj->list);
@@ -206,11 +206,12 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
206 } 206 }
207 207
208 list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) { 208 list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
209 struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id); 209 struct ib_cq *cq = uobj->object;
210 struct ib_uverbs_event_file *ev_file = cq->cq_context; 210 struct ib_uverbs_event_file *ev_file = cq->cq_context;
211 struct ib_ucq_object *ucq = 211 struct ib_ucq_object *ucq =
212 container_of(uobj, struct ib_ucq_object, uobject); 212 container_of(uobj, struct ib_ucq_object, uobject);
213 idr_remove(&ib_uverbs_cq_idr, uobj->id); 213
214 idr_remove_uobj(&ib_uverbs_cq_idr, uobj);
214 ib_destroy_cq(cq); 215 ib_destroy_cq(cq);
215 list_del(&uobj->list); 216 list_del(&uobj->list);
216 ib_uverbs_release_ucq(file, ev_file, ucq); 217 ib_uverbs_release_ucq(file, ev_file, ucq);
@@ -218,10 +219,11 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
218 } 219 }
219 220
220 list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) { 221 list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
221 struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id); 222 struct ib_srq *srq = uobj->object;
222 struct ib_uevent_object *uevent = 223 struct ib_uevent_object *uevent =
223 container_of(uobj, struct ib_uevent_object, uobject); 224 container_of(uobj, struct ib_uevent_object, uobject);
224 idr_remove(&ib_uverbs_srq_idr, uobj->id); 225
226 idr_remove_uobj(&ib_uverbs_srq_idr, uobj);
225 ib_destroy_srq(srq); 227 ib_destroy_srq(srq);
226 list_del(&uobj->list); 228 list_del(&uobj->list);
227 ib_uverbs_release_uevent(file, uevent); 229 ib_uverbs_release_uevent(file, uevent);
@@ -231,11 +233,11 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
231 /* XXX Free MWs */ 233 /* XXX Free MWs */
232 234
233 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { 235 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
234 struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id); 236 struct ib_mr *mr = uobj->object;
235 struct ib_device *mrdev = mr->device; 237 struct ib_device *mrdev = mr->device;
236 struct ib_umem_object *memobj; 238 struct ib_umem_object *memobj;
237 239
238 idr_remove(&ib_uverbs_mr_idr, uobj->id); 240 idr_remove_uobj(&ib_uverbs_mr_idr, uobj);
239 ib_dereg_mr(mr); 241 ib_dereg_mr(mr);
240 242
241 memobj = container_of(uobj, struct ib_umem_object, uobject); 243 memobj = container_of(uobj, struct ib_umem_object, uobject);
@@ -246,15 +248,14 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
246 } 248 }
247 249
248 list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) { 250 list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) {
249 struct ib_pd *pd = idr_find(&ib_uverbs_pd_idr, uobj->id); 251 struct ib_pd *pd = uobj->object;
250 idr_remove(&ib_uverbs_pd_idr, uobj->id); 252
253 idr_remove_uobj(&ib_uverbs_pd_idr, uobj);
251 ib_dealloc_pd(pd); 254 ib_dealloc_pd(pd);
252 list_del(&uobj->list); 255 list_del(&uobj->list);
253 kfree(uobj); 256 kfree(uobj);
254 } 257 }
255 258
256 mutex_unlock(&ib_uverbs_idr_mutex);
257
258 return context->device->dealloc_ucontext(context); 259 return context->device->dealloc_ucontext(context);
259} 260}
260 261
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 7ced208edacf..ee1f3a355666 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -697,8 +697,12 @@ struct ib_ucontext {
697struct ib_uobject { 697struct ib_uobject {
698 u64 user_handle; /* handle given to us by userspace */ 698 u64 user_handle; /* handle given to us by userspace */
699 struct ib_ucontext *context; /* associated user context */ 699 struct ib_ucontext *context; /* associated user context */
700 void *object; /* containing object */
700 struct list_head list; /* link to context's list */ 701 struct list_head list; /* link to context's list */
701 u32 id; /* index into kernel idr */ 702 u32 id; /* index into kernel idr */
703 struct kref ref;
704 struct rw_semaphore mutex; /* protects .live */
705 int live;
702}; 706};
703 707
704struct ib_umem { 708struct ib_umem {