aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 {