aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShamir Rabinovitch <shamir.rabinovitch@oracle.com>2019-03-31 12:10:04 -0400
committerJason Gunthorpe <jgg@mellanox.com>2019-04-01 13:55:36 -0400
commita6a3797df2741aa81f33fe48f609247dba98f3f7 (patch)
tree6f68ef594dec90b76928c7be5e1c60bed326c738
parent70f06b26f07ea42d158b41bba460ce06ffa3510a (diff)
IB: Pass uverbs_attr_bundle down uobject destroy path
Pass uverbs_attr_bundle down the uobject destroy path. The next patch will use this to eliminate the dependecy of the drivers in ib_x->uobject pointers. Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r--drivers/infiniband/core/rdma_core.c48
-rw-r--r--drivers/infiniband/core/rdma_core.h6
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c52
-rw-r--r--drivers/infiniband/core/uverbs_ioctl.c15
-rw-r--r--drivers/infiniband/core/uverbs_std_types.c27
-rw-r--r--drivers/infiniband/core/uverbs_std_types_counters.c3
-rw-r--r--drivers/infiniband/core/uverbs_std_types_cq.c3
-rw-r--r--drivers/infiniband/core/uverbs_std_types_dm.c3
-rw-r--r--drivers/infiniband/core/uverbs_std_types_flow_action.c3
-rw-r--r--drivers/infiniband/core/uverbs_std_types_mr.c3
-rw-r--r--drivers/infiniband/hw/mlx5/devx.c6
-rw-r--r--drivers/infiniband/hw/mlx5/flow.c3
-rw-r--r--include/rdma/uverbs_std_types.h10
-rw-r--r--include/rdma/uverbs_types.h12
14 files changed, 116 insertions, 78 deletions
diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c
index 0d18fb0e975d..d0a6755c0562 100644
--- a/drivers/infiniband/core/rdma_core.c
+++ b/drivers/infiniband/core/rdma_core.c
@@ -125,7 +125,8 @@ static void assert_uverbs_usecnt(struct ib_uobject *uobj,
125 * and consumes the kref on the uobj. 125 * and consumes the kref on the uobj.
126 */ 126 */
127static int uverbs_destroy_uobject(struct ib_uobject *uobj, 127static int uverbs_destroy_uobject(struct ib_uobject *uobj,
128 enum rdma_remove_reason reason) 128 enum rdma_remove_reason reason,
129 struct uverbs_attr_bundle *attrs)
129{ 130{
130 struct ib_uverbs_file *ufile = uobj->ufile; 131 struct ib_uverbs_file *ufile = uobj->ufile;
131 unsigned long flags; 132 unsigned long flags;
@@ -135,7 +136,8 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
135 assert_uverbs_usecnt(uobj, UVERBS_LOOKUP_WRITE); 136 assert_uverbs_usecnt(uobj, UVERBS_LOOKUP_WRITE);
136 137
137 if (uobj->object) { 138 if (uobj->object) {
138 ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason); 139 ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason,
140 attrs);
139 if (ret) { 141 if (ret) {
140 if (ib_is_destroy_retryable(ret, reason, uobj)) 142 if (ib_is_destroy_retryable(ret, reason, uobj))
141 return ret; 143 return ret;
@@ -196,7 +198,7 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
196 * version requires the caller to have already obtained an 198 * version requires the caller to have already obtained an
197 * LOOKUP_DESTROY uobject kref. 199 * LOOKUP_DESTROY uobject kref.
198 */ 200 */
199int uobj_destroy(struct ib_uobject *uobj) 201int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs)
200{ 202{
201 struct ib_uverbs_file *ufile = uobj->ufile; 203 struct ib_uverbs_file *ufile = uobj->ufile;
202 int ret; 204 int ret;
@@ -207,7 +209,7 @@ int uobj_destroy(struct ib_uobject *uobj)
207 if (ret) 209 if (ret)
208 goto out_unlock; 210 goto out_unlock;
209 211
210 ret = uverbs_destroy_uobject(uobj, RDMA_REMOVE_DESTROY); 212 ret = uverbs_destroy_uobject(uobj, RDMA_REMOVE_DESTROY, attrs);
211 if (ret) { 213 if (ret) {
212 atomic_set(&uobj->usecnt, 0); 214 atomic_set(&uobj->usecnt, 0);
213 goto out_unlock; 215 goto out_unlock;
@@ -234,7 +236,7 @@ struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
234 if (IS_ERR(uobj)) 236 if (IS_ERR(uobj))
235 return uobj; 237 return uobj;
236 238
237 ret = uobj_destroy(uobj); 239 ret = uobj_destroy(uobj, attrs);
238 if (ret) { 240 if (ret) {
239 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY); 241 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
240 return ERR_PTR(ret); 242 return ERR_PTR(ret);
@@ -533,12 +535,13 @@ static void alloc_abort_idr_uobject(struct ib_uobject *uobj)
533} 535}
534 536
535static int __must_check destroy_hw_idr_uobject(struct ib_uobject *uobj, 537static int __must_check destroy_hw_idr_uobject(struct ib_uobject *uobj,
536 enum rdma_remove_reason why) 538 enum rdma_remove_reason why,
539 struct uverbs_attr_bundle *attrs)
537{ 540{
538 const struct uverbs_obj_idr_type *idr_type = 541 const struct uverbs_obj_idr_type *idr_type =
539 container_of(uobj->uapi_object->type_attrs, 542 container_of(uobj->uapi_object->type_attrs,
540 struct uverbs_obj_idr_type, type); 543 struct uverbs_obj_idr_type, type);
541 int ret = idr_type->destroy_object(uobj, why); 544 int ret = idr_type->destroy_object(uobj, why, attrs);
542 545
543 /* 546 /*
544 * We can only fail gracefully if the user requested to destroy the 547 * We can only fail gracefully if the user requested to destroy the
@@ -572,7 +575,8 @@ static void alloc_abort_fd_uobject(struct ib_uobject *uobj)
572} 575}
573 576
574static int __must_check destroy_hw_fd_uobject(struct ib_uobject *uobj, 577static int __must_check destroy_hw_fd_uobject(struct ib_uobject *uobj,
575 enum rdma_remove_reason why) 578 enum rdma_remove_reason why,
579 struct uverbs_attr_bundle *attrs)
576{ 580{
577 const struct uverbs_obj_fd_type *fd_type = container_of( 581 const struct uverbs_obj_fd_type *fd_type = container_of(
578 uobj->uapi_object->type_attrs, struct uverbs_obj_fd_type, type); 582 uobj->uapi_object->type_attrs, struct uverbs_obj_fd_type, type);
@@ -648,7 +652,8 @@ static int alloc_commit_fd_uobject(struct ib_uobject *uobj)
648 * caller can no longer assume uobj is valid. If this function fails it 652 * caller can no longer assume uobj is valid. If this function fails it
649 * destroys the uboject, including the attached HW object. 653 * destroys the uboject, including the attached HW object.
650 */ 654 */
651int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj) 655int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj,
656 struct uverbs_attr_bundle *attrs)
652{ 657{
653 struct ib_uverbs_file *ufile = uobj->ufile; 658 struct ib_uverbs_file *ufile = uobj->ufile;
654 int ret; 659 int ret;
@@ -656,7 +661,7 @@ int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj)
656 /* alloc_commit consumes the uobj kref */ 661 /* alloc_commit consumes the uobj kref */
657 ret = uobj->uapi_object->type_class->alloc_commit(uobj); 662 ret = uobj->uapi_object->type_class->alloc_commit(uobj);
658 if (ret) { 663 if (ret) {
659 uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT); 664 uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT, attrs);
660 up_read(&ufile->hw_destroy_rwsem); 665 up_read(&ufile->hw_destroy_rwsem);
661 return ret; 666 return ret;
662 } 667 }
@@ -680,12 +685,13 @@ int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj)
680 * This consumes the kref for uobj. It is up to the caller to unwind the HW 685 * This consumes the kref for uobj. It is up to the caller to unwind the HW
681 * object and anything else connected to uobj before calling this. 686 * object and anything else connected to uobj before calling this.
682 */ 687 */
683void rdma_alloc_abort_uobject(struct ib_uobject *uobj) 688void rdma_alloc_abort_uobject(struct ib_uobject *uobj,
689 struct uverbs_attr_bundle *attrs)
684{ 690{
685 struct ib_uverbs_file *ufile = uobj->ufile; 691 struct ib_uverbs_file *ufile = uobj->ufile;
686 692
687 uobj->object = NULL; 693 uobj->object = NULL;
688 uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT); 694 uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT, attrs);
689 695
690 /* Matches the down_read in rdma_alloc_begin_uobject */ 696 /* Matches the down_read in rdma_alloc_begin_uobject */
691 up_read(&ufile->hw_destroy_rwsem); 697 up_read(&ufile->hw_destroy_rwsem);
@@ -787,6 +793,10 @@ void uverbs_close_fd(struct file *f)
787{ 793{
788 struct ib_uobject *uobj = f->private_data; 794 struct ib_uobject *uobj = f->private_data;
789 struct ib_uverbs_file *ufile = uobj->ufile; 795 struct ib_uverbs_file *ufile = uobj->ufile;
796 struct uverbs_attr_bundle attrs = {
797 .context = uobj->context,
798 .ufile = ufile,
799 };
790 800
791 if (down_read_trylock(&ufile->hw_destroy_rwsem)) { 801 if (down_read_trylock(&ufile->hw_destroy_rwsem)) {
792 /* 802 /*
@@ -796,7 +806,7 @@ void uverbs_close_fd(struct file *f)
796 * write lock here, or we have a kernel bug. 806 * write lock here, or we have a kernel bug.
797 */ 807 */
798 WARN_ON(uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE)); 808 WARN_ON(uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE));
799 uverbs_destroy_uobject(uobj, RDMA_REMOVE_CLOSE); 809 uverbs_destroy_uobject(uobj, RDMA_REMOVE_CLOSE, &attrs);
800 up_read(&ufile->hw_destroy_rwsem); 810 up_read(&ufile->hw_destroy_rwsem);
801 } 811 }
802 812
@@ -845,6 +855,7 @@ static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,
845{ 855{
846 struct ib_uobject *obj, *next_obj; 856 struct ib_uobject *obj, *next_obj;
847 int ret = -EINVAL; 857 int ret = -EINVAL;
858 struct uverbs_attr_bundle attrs = { .ufile = ufile };
848 859
849 /* 860 /*
850 * This shouldn't run while executing other commands on this 861 * This shouldn't run while executing other commands on this
@@ -856,12 +867,13 @@ static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,
856 * other threads (which might still use the FDs) chance to run. 867 * other threads (which might still use the FDs) chance to run.
857 */ 868 */
858 list_for_each_entry_safe(obj, next_obj, &ufile->uobjects, list) { 869 list_for_each_entry_safe(obj, next_obj, &ufile->uobjects, list) {
870 attrs.context = obj->context;
859 /* 871 /*
860 * if we hit this WARN_ON, that means we are 872 * if we hit this WARN_ON, that means we are
861 * racing with a lookup_get. 873 * racing with a lookup_get.
862 */ 874 */
863 WARN_ON(uverbs_try_lock_object(obj, UVERBS_LOOKUP_WRITE)); 875 WARN_ON(uverbs_try_lock_object(obj, UVERBS_LOOKUP_WRITE));
864 if (!uverbs_destroy_uobject(obj, reason)) 876 if (!uverbs_destroy_uobject(obj, reason, &attrs))
865 ret = 0; 877 ret = 0;
866 else 878 else
867 atomic_set(&obj->usecnt, 0); 879 atomic_set(&obj->usecnt, 0);
@@ -966,8 +978,8 @@ uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
966} 978}
967 979
968int uverbs_finalize_object(struct ib_uobject *uobj, 980int uverbs_finalize_object(struct ib_uobject *uobj,
969 enum uverbs_obj_access access, 981 enum uverbs_obj_access access, bool commit,
970 bool commit) 982 struct uverbs_attr_bundle *attrs)
971{ 983{
972 int ret = 0; 984 int ret = 0;
973 985
@@ -990,9 +1002,9 @@ int uverbs_finalize_object(struct ib_uobject *uobj,
990 break; 1002 break;
991 case UVERBS_ACCESS_NEW: 1003 case UVERBS_ACCESS_NEW:
992 if (commit) 1004 if (commit)
993 ret = rdma_alloc_commit_uobject(uobj); 1005 ret = rdma_alloc_commit_uobject(uobj, attrs);
994 else 1006 else
995 rdma_alloc_abort_uobject(uobj); 1007 rdma_alloc_abort_uobject(uobj, attrs);
996 break; 1008 break;
997 default: 1009 default:
998 WARN_ON(true); 1010 WARN_ON(true);
diff --git a/drivers/infiniband/core/rdma_core.h b/drivers/infiniband/core/rdma_core.h
index d91d44f4fa89..5445323629b5 100644
--- a/drivers/infiniband/core/rdma_core.h
+++ b/drivers/infiniband/core/rdma_core.h
@@ -48,7 +48,7 @@ struct ib_uverbs_device;
48void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile, 48void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile,
49 enum rdma_remove_reason reason); 49 enum rdma_remove_reason reason);
50 50
51int uobj_destroy(struct ib_uobject *uobj); 51int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs);
52 52
53/* 53/*
54 * uverbs_uobject_get is called in order to increase the reference count on 54 * uverbs_uobject_get is called in order to increase the reference count on
@@ -102,8 +102,8 @@ uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
102 * object. 102 * object.
103 */ 103 */
104int uverbs_finalize_object(struct ib_uobject *uobj, 104int uverbs_finalize_object(struct ib_uobject *uobj,
105 enum uverbs_obj_access access, 105 enum uverbs_obj_access access, bool commit,
106 bool commit); 106 struct uverbs_attr_bundle *attrs);
107 107
108int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx); 108int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);
109 109
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 5115a050f313..726275288887 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -436,7 +436,7 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
436 if (ret) 436 if (ret)
437 goto err_copy; 437 goto err_copy;
438 438
439 return uobj_alloc_commit(uobj); 439 return uobj_alloc_commit(uobj, attrs);
440 440
441err_copy: 441err_copy:
442 ib_dealloc_pd(pd); 442 ib_dealloc_pd(pd);
@@ -444,7 +444,7 @@ err_copy:
444err_alloc: 444err_alloc:
445 kfree(pd); 445 kfree(pd);
446err: 446err:
447 uobj_alloc_abort(uobj); 447 uobj_alloc_abort(uobj, attrs);
448 return ret; 448 return ret;
449} 449}
450 450
@@ -633,7 +633,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
633 633
634 mutex_unlock(&ibudev->xrcd_tree_mutex); 634 mutex_unlock(&ibudev->xrcd_tree_mutex);
635 635
636 return uobj_alloc_commit(&obj->uobject); 636 return uobj_alloc_commit(&obj->uobject, attrs);
637 637
638err_copy: 638err_copy:
639 if (inode) { 639 if (inode) {
@@ -646,7 +646,7 @@ err_dealloc_xrcd:
646 ib_dealloc_xrcd(xrcd); 646 ib_dealloc_xrcd(xrcd);
647 647
648err: 648err:
649 uobj_alloc_abort(&obj->uobject); 649 uobj_alloc_abort(&obj->uobject, attrs);
650 650
651err_tree_mutex_unlock: 651err_tree_mutex_unlock:
652 if (f.file) 652 if (f.file)
@@ -763,7 +763,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
763 763
764 uobj_put_obj_read(pd); 764 uobj_put_obj_read(pd);
765 765
766 return uobj_alloc_commit(uobj); 766 return uobj_alloc_commit(uobj, attrs);
767 767
768err_copy: 768err_copy:
769 ib_dereg_mr(mr); 769 ib_dereg_mr(mr);
@@ -772,7 +772,7 @@ err_put:
772 uobj_put_obj_read(pd); 772 uobj_put_obj_read(pd);
773 773
774err_free: 774err_free:
775 uobj_alloc_abort(uobj); 775 uobj_alloc_abort(uobj, attrs);
776 return ret; 776 return ret;
777} 777}
778 778
@@ -917,14 +917,14 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs)
917 goto err_copy; 917 goto err_copy;
918 918
919 uobj_put_obj_read(pd); 919 uobj_put_obj_read(pd);
920 return uobj_alloc_commit(uobj); 920 return uobj_alloc_commit(uobj, attrs);
921 921
922err_copy: 922err_copy:
923 uverbs_dealloc_mw(mw); 923 uverbs_dealloc_mw(mw);
924err_put: 924err_put:
925 uobj_put_obj_read(pd); 925 uobj_put_obj_read(pd);
926err_free: 926err_free:
927 uobj_alloc_abort(uobj); 927 uobj_alloc_abort(uobj, attrs);
928 return ret; 928 return ret;
929} 929}
930 930
@@ -965,11 +965,11 @@ static int ib_uverbs_create_comp_channel(struct uverbs_attr_bundle *attrs)
965 965
966 ret = uverbs_response(attrs, &resp, sizeof(resp)); 966 ret = uverbs_response(attrs, &resp, sizeof(resp));
967 if (ret) { 967 if (ret) {
968 uobj_alloc_abort(uobj); 968 uobj_alloc_abort(uobj, attrs);
969 return ret; 969 return ret;
970 } 970 }
971 971
972 return uobj_alloc_commit(uobj); 972 return uobj_alloc_commit(uobj, attrs);
973} 973}
974 974
975static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs, 975static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
@@ -1036,7 +1036,7 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
1036 if (ret) 1036 if (ret)
1037 goto err_cb; 1037 goto err_cb;
1038 1038
1039 ret = uobj_alloc_commit(&obj->uobject); 1039 ret = uobj_alloc_commit(&obj->uobject, attrs);
1040 if (ret) 1040 if (ret)
1041 return ERR_PTR(ret); 1041 return ERR_PTR(ret);
1042 return obj; 1042 return obj;
@@ -1049,7 +1049,7 @@ err_file:
1049 ib_uverbs_release_ucq(attrs->ufile, ev_file, obj); 1049 ib_uverbs_release_ucq(attrs->ufile, ev_file, obj);
1050 1050
1051err: 1051err:
1052 uobj_alloc_abort(&obj->uobject); 1052 uobj_alloc_abort(&obj->uobject, attrs);
1053 1053
1054 return ERR_PTR(ret); 1054 return ERR_PTR(ret);
1055} 1055}
@@ -1477,7 +1477,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
1477 if (ind_tbl) 1477 if (ind_tbl)
1478 uobj_put_obj_read(ind_tbl); 1478 uobj_put_obj_read(ind_tbl);
1479 1479
1480 return uobj_alloc_commit(&obj->uevent.uobject); 1480 return uobj_alloc_commit(&obj->uevent.uobject, attrs);
1481err_cb: 1481err_cb:
1482 ib_destroy_qp(qp); 1482 ib_destroy_qp(qp);
1483 1483
@@ -1495,7 +1495,7 @@ err_put:
1495 if (ind_tbl) 1495 if (ind_tbl)
1496 uobj_put_obj_read(ind_tbl); 1496 uobj_put_obj_read(ind_tbl);
1497 1497
1498 uobj_alloc_abort(&obj->uevent.uobject); 1498 uobj_alloc_abort(&obj->uevent.uobject, attrs);
1499 return ret; 1499 return ret;
1500} 1500}
1501 1501
@@ -1609,14 +1609,14 @@ static int ib_uverbs_open_qp(struct uverbs_attr_bundle *attrs)
1609 qp->uobject = &obj->uevent.uobject; 1609 qp->uobject = &obj->uevent.uobject;
1610 uobj_put_read(xrcd_uobj); 1610 uobj_put_read(xrcd_uobj);
1611 1611
1612 return uobj_alloc_commit(&obj->uevent.uobject); 1612 return uobj_alloc_commit(&obj->uevent.uobject, attrs);
1613 1613
1614err_destroy: 1614err_destroy:
1615 ib_destroy_qp(qp); 1615 ib_destroy_qp(qp);
1616err_xrcd: 1616err_xrcd:
1617 uobj_put_read(xrcd_uobj); 1617 uobj_put_read(xrcd_uobj);
1618err_put: 1618err_put:
1619 uobj_alloc_abort(&obj->uevent.uobject); 1619 uobj_alloc_abort(&obj->uevent.uobject, attrs);
1620 return ret; 1620 return ret;
1621} 1621}
1622 1622
@@ -2451,7 +2451,7 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs)
2451 goto err_copy; 2451 goto err_copy;
2452 2452
2453 uobj_put_obj_read(pd); 2453 uobj_put_obj_read(pd);
2454 return uobj_alloc_commit(uobj); 2454 return uobj_alloc_commit(uobj, attrs);
2455 2455
2456err_copy: 2456err_copy:
2457 rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE); 2457 rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
@@ -2460,7 +2460,7 @@ err_put:
2460 uobj_put_obj_read(pd); 2460 uobj_put_obj_read(pd);
2461 2461
2462err: 2462err:
2463 uobj_alloc_abort(uobj); 2463 uobj_alloc_abort(uobj, attrs);
2464 return ret; 2464 return ret;
2465} 2465}
2466 2466
@@ -2962,7 +2962,7 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
2962 2962
2963 uobj_put_obj_read(pd); 2963 uobj_put_obj_read(pd);
2964 uobj_put_obj_read(cq); 2964 uobj_put_obj_read(cq);
2965 return uobj_alloc_commit(&obj->uevent.uobject); 2965 return uobj_alloc_commit(&obj->uevent.uobject, attrs);
2966 2966
2967err_copy: 2967err_copy:
2968 ib_destroy_wq(wq); 2968 ib_destroy_wq(wq);
@@ -2971,7 +2971,7 @@ err_put_cq:
2971err_put_pd: 2971err_put_pd:
2972 uobj_put_obj_read(pd); 2972 uobj_put_obj_read(pd);
2973err_uobj: 2973err_uobj:
2974 uobj_alloc_abort(&obj->uevent.uobject); 2974 uobj_alloc_abort(&obj->uevent.uobject, attrs);
2975 2975
2976 return err; 2976 return err;
2977} 2977}
@@ -3136,12 +3136,12 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs)
3136 for (j = 0; j < num_read_wqs; j++) 3136 for (j = 0; j < num_read_wqs; j++)
3137 uobj_put_obj_read(wqs[j]); 3137 uobj_put_obj_read(wqs[j]);
3138 3138
3139 return uobj_alloc_commit(uobj); 3139 return uobj_alloc_commit(uobj, attrs);
3140 3140
3141err_copy: 3141err_copy:
3142 ib_destroy_rwq_ind_table(rwq_ind_tbl); 3142 ib_destroy_rwq_ind_table(rwq_ind_tbl);
3143err_uobj: 3143err_uobj:
3144 uobj_alloc_abort(uobj); 3144 uobj_alloc_abort(uobj, attrs);
3145put_wqs: 3145put_wqs:
3146 for (j = 0; j < num_read_wqs; j++) 3146 for (j = 0; j < num_read_wqs; j++)
3147 uobj_put_obj_read(wqs[j]); 3147 uobj_put_obj_read(wqs[j]);
@@ -3314,7 +3314,7 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs)
3314 kfree(flow_attr); 3314 kfree(flow_attr);
3315 if (cmd.flow_attr.num_of_specs) 3315 if (cmd.flow_attr.num_of_specs)
3316 kfree(kern_flow_attr); 3316 kfree(kern_flow_attr);
3317 return uobj_alloc_commit(uobj); 3317 return uobj_alloc_commit(uobj, attrs);
3318err_copy: 3318err_copy:
3319 if (!qp->device->ops.destroy_flow(flow_id)) 3319 if (!qp->device->ops.destroy_flow(flow_id))
3320 atomic_dec(&qp->usecnt); 3320 atomic_dec(&qp->usecnt);
@@ -3325,7 +3325,7 @@ err_free_flow_attr:
3325err_put: 3325err_put:
3326 uobj_put_obj_read(qp); 3326 uobj_put_obj_read(qp);
3327err_uobj: 3327err_uobj:
3328 uobj_alloc_abort(uobj); 3328 uobj_alloc_abort(uobj, attrs);
3329err_free_attr: 3329err_free_attr:
3330 if (cmd.flow_attr.num_of_specs) 3330 if (cmd.flow_attr.num_of_specs)
3331 kfree(kern_flow_attr); 3331 kfree(kern_flow_attr);
@@ -3458,7 +3458,7 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
3458 uobj_put_obj_read(attr.ext.cq); 3458 uobj_put_obj_read(attr.ext.cq);
3459 3459
3460 uobj_put_obj_read(pd); 3460 uobj_put_obj_read(pd);
3461 return uobj_alloc_commit(&obj->uevent.uobject); 3461 return uobj_alloc_commit(&obj->uevent.uobject, attrs);
3462 3462
3463err_copy: 3463err_copy:
3464 ib_destroy_srq(srq); 3464 ib_destroy_srq(srq);
@@ -3477,7 +3477,7 @@ err_put_xrcd:
3477 } 3477 }
3478 3478
3479err: 3479err:
3480 uobj_alloc_abort(&obj->uevent.uobject); 3480 uobj_alloc_abort(&obj->uevent.uobject, attrs);
3481 return ret; 3481 return ret;
3482} 3482}
3483 3483
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c
index 5255e00b91cc..cfbef25b3a73 100644
--- a/drivers/infiniband/core/uverbs_ioctl.c
+++ b/drivers/infiniband/core/uverbs_ioctl.c
@@ -222,7 +222,7 @@ static int uverbs_process_idrs_array(struct bundle_priv *pbundle,
222 222
223static int uverbs_free_idrs_array(const struct uverbs_api_attr *attr_uapi, 223static int uverbs_free_idrs_array(const struct uverbs_api_attr *attr_uapi,
224 struct uverbs_objs_arr_attr *attr, 224 struct uverbs_objs_arr_attr *attr,
225 bool commit) 225 bool commit, struct uverbs_attr_bundle *attrs)
226{ 226{
227 const struct uverbs_attr_spec *spec = &attr_uapi->spec; 227 const struct uverbs_attr_spec *spec = &attr_uapi->spec;
228 int current_ret; 228 int current_ret;
@@ -230,8 +230,9 @@ static int uverbs_free_idrs_array(const struct uverbs_api_attr *attr_uapi,
230 size_t i; 230 size_t i;
231 231
232 for (i = 0; i != attr->len; i++) { 232 for (i = 0; i != attr->len; i++) {
233 current_ret = uverbs_finalize_object( 233 current_ret = uverbs_finalize_object(attr->uobjects[i],
234 attr->uobjects[i], spec->u2.objs_arr.access, commit); 234 spec->u2.objs_arr.access,
235 commit, attrs);
235 if (!ret) 236 if (!ret)
236 ret = current_ret; 237 ret = current_ret;
237 } 238 }
@@ -457,7 +458,7 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
457 struct uverbs_obj_attr *destroy_attr = 458 struct uverbs_obj_attr *destroy_attr =
458 &pbundle->bundle.attrs[destroy_bkey].obj_attr; 459 &pbundle->bundle.attrs[destroy_bkey].obj_attr;
459 460
460 ret = uobj_destroy(destroy_attr->uobject); 461 ret = uobj_destroy(destroy_attr->uobject, &pbundle->bundle);
461 if (ret) 462 if (ret)
462 return ret; 463 return ret;
463 __clear_bit(destroy_bkey, pbundle->uobj_finalize); 464 __clear_bit(destroy_bkey, pbundle->uobj_finalize);
@@ -508,7 +509,8 @@ static int bundle_destroy(struct bundle_priv *pbundle, bool commit)
508 509
509 current_ret = uverbs_finalize_object( 510 current_ret = uverbs_finalize_object(
510 attr->obj_attr.uobject, 511 attr->obj_attr.uobject,
511 attr->obj_attr.attr_elm->spec.u.obj.access, commit); 512 attr->obj_attr.attr_elm->spec.u.obj.access, commit,
513 &pbundle->bundle);
512 if (!ret) 514 if (!ret)
513 ret = current_ret; 515 ret = current_ret;
514 } 516 }
@@ -531,7 +533,8 @@ static int bundle_destroy(struct bundle_priv *pbundle, bool commit)
531 533
532 if (attr_uapi->spec.type == UVERBS_ATTR_TYPE_IDRS_ARRAY) { 534 if (attr_uapi->spec.type == UVERBS_ATTR_TYPE_IDRS_ARRAY) {
533 current_ret = uverbs_free_idrs_array( 535 current_ret = uverbs_free_idrs_array(
534 attr_uapi, &attr->objs_arr_attr, commit); 536 attr_uapi, &attr->objs_arr_attr, commit,
537 &pbundle->bundle);
535 if (!ret) 538 if (!ret)
536 ret = current_ret; 539 ret = current_ret;
537 } 540 }
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index f224cb727224..a1b22fca057e 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -40,14 +40,16 @@
40#include "uverbs.h" 40#include "uverbs.h"
41 41
42static int uverbs_free_ah(struct ib_uobject *uobject, 42static int uverbs_free_ah(struct ib_uobject *uobject,
43 enum rdma_remove_reason why) 43 enum rdma_remove_reason why,
44 struct uverbs_attr_bundle *attrs)
44{ 45{
45 return rdma_destroy_ah((struct ib_ah *)uobject->object, 46 return rdma_destroy_ah((struct ib_ah *)uobject->object,
46 RDMA_DESTROY_AH_SLEEPABLE); 47 RDMA_DESTROY_AH_SLEEPABLE);
47} 48}
48 49
49static int uverbs_free_flow(struct ib_uobject *uobject, 50static int uverbs_free_flow(struct ib_uobject *uobject,
50 enum rdma_remove_reason why) 51 enum rdma_remove_reason why,
52 struct uverbs_attr_bundle *attrs)
51{ 53{
52 struct ib_flow *flow = (struct ib_flow *)uobject->object; 54 struct ib_flow *flow = (struct ib_flow *)uobject->object;
53 struct ib_uflow_object *uflow = 55 struct ib_uflow_object *uflow =
@@ -66,13 +68,15 @@ static int uverbs_free_flow(struct ib_uobject *uobject,
66} 68}
67 69
68static int uverbs_free_mw(struct ib_uobject *uobject, 70static int uverbs_free_mw(struct ib_uobject *uobject,
69 enum rdma_remove_reason why) 71 enum rdma_remove_reason why,
72 struct uverbs_attr_bundle *attrs)
70{ 73{
71 return uverbs_dealloc_mw((struct ib_mw *)uobject->object); 74 return uverbs_dealloc_mw((struct ib_mw *)uobject->object);
72} 75}
73 76
74static int uverbs_free_qp(struct ib_uobject *uobject, 77static int uverbs_free_qp(struct ib_uobject *uobject,
75 enum rdma_remove_reason why) 78 enum rdma_remove_reason why,
79 struct uverbs_attr_bundle *attrs)
76{ 80{
77 struct ib_qp *qp = uobject->object; 81 struct ib_qp *qp = uobject->object;
78 struct ib_uqp_object *uqp = 82 struct ib_uqp_object *uqp =
@@ -105,7 +109,8 @@ static int uverbs_free_qp(struct ib_uobject *uobject,
105} 109}
106 110
107static int uverbs_free_rwq_ind_tbl(struct ib_uobject *uobject, 111static int uverbs_free_rwq_ind_tbl(struct ib_uobject *uobject,
108 enum rdma_remove_reason why) 112 enum rdma_remove_reason why,
113 struct uverbs_attr_bundle *attrs)
109{ 114{
110 struct ib_rwq_ind_table *rwq_ind_tbl = uobject->object; 115 struct ib_rwq_ind_table *rwq_ind_tbl = uobject->object;
111 struct ib_wq **ind_tbl = rwq_ind_tbl->ind_tbl; 116 struct ib_wq **ind_tbl = rwq_ind_tbl->ind_tbl;
@@ -120,7 +125,8 @@ static int uverbs_free_rwq_ind_tbl(struct ib_uobject *uobject,
120} 125}
121 126
122static int uverbs_free_wq(struct ib_uobject *uobject, 127static int uverbs_free_wq(struct ib_uobject *uobject,
123 enum rdma_remove_reason why) 128 enum rdma_remove_reason why,
129 struct uverbs_attr_bundle *attrs)
124{ 130{
125 struct ib_wq *wq = uobject->object; 131 struct ib_wq *wq = uobject->object;
126 struct ib_uwq_object *uwq = 132 struct ib_uwq_object *uwq =
@@ -136,7 +142,8 @@ static int uverbs_free_wq(struct ib_uobject *uobject,
136} 142}
137 143
138static int uverbs_free_srq(struct ib_uobject *uobject, 144static int uverbs_free_srq(struct ib_uobject *uobject,
139 enum rdma_remove_reason why) 145 enum rdma_remove_reason why,
146 struct uverbs_attr_bundle *attrs)
140{ 147{
141 struct ib_srq *srq = uobject->object; 148 struct ib_srq *srq = uobject->object;
142 struct ib_uevent_object *uevent = 149 struct ib_uevent_object *uevent =
@@ -160,7 +167,8 @@ static int uverbs_free_srq(struct ib_uobject *uobject,
160} 167}
161 168
162static int uverbs_free_xrcd(struct ib_uobject *uobject, 169static int uverbs_free_xrcd(struct ib_uobject *uobject,
163 enum rdma_remove_reason why) 170 enum rdma_remove_reason why,
171 struct uverbs_attr_bundle *attrs)
164{ 172{
165 struct ib_xrcd *xrcd = uobject->object; 173 struct ib_xrcd *xrcd = uobject->object;
166 struct ib_uxrcd_object *uxrcd = 174 struct ib_uxrcd_object *uxrcd =
@@ -179,7 +187,8 @@ static int uverbs_free_xrcd(struct ib_uobject *uobject,
179} 187}
180 188
181static int uverbs_free_pd(struct ib_uobject *uobject, 189static int uverbs_free_pd(struct ib_uobject *uobject,
182 enum rdma_remove_reason why) 190 enum rdma_remove_reason why,
191 struct uverbs_attr_bundle *attrs)
183{ 192{
184 struct ib_pd *pd = uobject->object; 193 struct ib_pd *pd = uobject->object;
185 int ret; 194 int ret;
diff --git a/drivers/infiniband/core/uverbs_std_types_counters.c b/drivers/infiniband/core/uverbs_std_types_counters.c
index 7880d50165ed..87aaf91072e3 100644
--- a/drivers/infiniband/core/uverbs_std_types_counters.c
+++ b/drivers/infiniband/core/uverbs_std_types_counters.c
@@ -36,7 +36,8 @@
36#include <rdma/uverbs_std_types.h> 36#include <rdma/uverbs_std_types.h>
37 37
38static int uverbs_free_counters(struct ib_uobject *uobject, 38static int uverbs_free_counters(struct ib_uobject *uobject,
39 enum rdma_remove_reason why) 39 enum rdma_remove_reason why,
40 struct uverbs_attr_bundle *attrs)
40{ 41{
41 struct ib_counters *counters = uobject->object; 42 struct ib_counters *counters = uobject->object;
42 int ret; 43 int ret;
diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c
index a59ea89e3f2b..5664a8f48527 100644
--- a/drivers/infiniband/core/uverbs_std_types_cq.c
+++ b/drivers/infiniband/core/uverbs_std_types_cq.c
@@ -35,7 +35,8 @@
35#include "uverbs.h" 35#include "uverbs.h"
36 36
37static int uverbs_free_cq(struct ib_uobject *uobject, 37static int uverbs_free_cq(struct ib_uobject *uobject,
38 enum rdma_remove_reason why) 38 enum rdma_remove_reason why,
39 struct uverbs_attr_bundle *attrs)
39{ 40{
40 struct ib_cq *cq = uobject->object; 41 struct ib_cq *cq = uobject->object;
41 struct ib_uverbs_event_queue *ev_queue = cq->cq_context; 42 struct ib_uverbs_event_queue *ev_queue = cq->cq_context;
diff --git a/drivers/infiniband/core/uverbs_std_types_dm.c b/drivers/infiniband/core/uverbs_std_types_dm.c
index de3f04a4398c..50d71522e1cd 100644
--- a/drivers/infiniband/core/uverbs_std_types_dm.c
+++ b/drivers/infiniband/core/uverbs_std_types_dm.c
@@ -35,7 +35,8 @@
35#include <rdma/uverbs_std_types.h> 35#include <rdma/uverbs_std_types.h>
36 36
37static int uverbs_free_dm(struct ib_uobject *uobject, 37static int uverbs_free_dm(struct ib_uobject *uobject,
38 enum rdma_remove_reason why) 38 enum rdma_remove_reason why,
39 struct uverbs_attr_bundle *attrs)
39{ 40{
40 struct ib_dm *dm = uobject->object; 41 struct ib_dm *dm = uobject->object;
41 int ret; 42 int ret;
diff --git a/drivers/infiniband/core/uverbs_std_types_flow_action.c b/drivers/infiniband/core/uverbs_std_types_flow_action.c
index 3a87b16a93b3..d6dbc1d580e5 100644
--- a/drivers/infiniband/core/uverbs_std_types_flow_action.c
+++ b/drivers/infiniband/core/uverbs_std_types_flow_action.c
@@ -35,7 +35,8 @@
35#include <rdma/uverbs_std_types.h> 35#include <rdma/uverbs_std_types.h>
36 36
37static int uverbs_free_flow_action(struct ib_uobject *uobject, 37static int uverbs_free_flow_action(struct ib_uobject *uobject,
38 enum rdma_remove_reason why) 38 enum rdma_remove_reason why,
39 struct uverbs_attr_bundle *attrs)
39{ 40{
40 struct ib_flow_action *action = uobject->object; 41 struct ib_flow_action *action = uobject->object;
41 int ret; 42 int ret;
diff --git a/drivers/infiniband/core/uverbs_std_types_mr.c b/drivers/infiniband/core/uverbs_std_types_mr.c
index 3b4bf6370333..a74b73f684d4 100644
--- a/drivers/infiniband/core/uverbs_std_types_mr.c
+++ b/drivers/infiniband/core/uverbs_std_types_mr.c
@@ -35,7 +35,8 @@
35#include <rdma/uverbs_std_types.h> 35#include <rdma/uverbs_std_types.h>
36 36
37static int uverbs_free_mr(struct ib_uobject *uobject, 37static int uverbs_free_mr(struct ib_uobject *uobject,
38 enum rdma_remove_reason why) 38 enum rdma_remove_reason why,
39 struct uverbs_attr_bundle *attrs)
39{ 40{
40 return ib_dereg_mr((struct ib_mr *)uobject->object); 41 return ib_dereg_mr((struct ib_mr *)uobject->object);
41} 42}
diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c
index fa8d2a9229fa..0770dcc74add 100644
--- a/drivers/infiniband/hw/mlx5/devx.c
+++ b/drivers/infiniband/hw/mlx5/devx.c
@@ -1117,7 +1117,8 @@ static void devx_cleanup_mkey(struct devx_obj *obj)
1117} 1117}
1118 1118
1119static int devx_obj_cleanup(struct ib_uobject *uobject, 1119static int devx_obj_cleanup(struct ib_uobject *uobject,
1120 enum rdma_remove_reason why) 1120 enum rdma_remove_reason why,
1121 struct uverbs_attr_bundle *attrs)
1121{ 1122{
1122 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 1123 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
1123 struct devx_obj *obj = uobject->object; 1124 struct devx_obj *obj = uobject->object;
@@ -1599,7 +1600,8 @@ err_obj_free:
1599} 1600}
1600 1601
1601static int devx_umem_cleanup(struct ib_uobject *uobject, 1602static int devx_umem_cleanup(struct ib_uobject *uobject,
1602 enum rdma_remove_reason why) 1603 enum rdma_remove_reason why,
1604 struct uverbs_attr_bundle *attrs)
1603{ 1605{
1604 struct devx_umem *obj = uobject->object; 1606 struct devx_umem *obj = uobject->object;
1605 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)]; 1607 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
diff --git a/drivers/infiniband/hw/mlx5/flow.c b/drivers/infiniband/hw/mlx5/flow.c
index 798591a18484..e8c3847a1a10 100644
--- a/drivers/infiniband/hw/mlx5/flow.c
+++ b/drivers/infiniband/hw/mlx5/flow.c
@@ -189,7 +189,8 @@ err_out:
189} 189}
190 190
191static int flow_matcher_cleanup(struct ib_uobject *uobject, 191static int flow_matcher_cleanup(struct ib_uobject *uobject,
192 enum rdma_remove_reason why) 192 enum rdma_remove_reason why,
193 struct uverbs_attr_bundle *attrs)
193{ 194{
194 struct mlx5_ib_flow_matcher *obj = uobject->object; 195 struct mlx5_ib_flow_matcher *obj = uobject->object;
195 int ret; 196 int ret;
diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h
index 2d0e6287e43a..b9226a5cdfd7 100644
--- a/include/rdma/uverbs_std_types.h
+++ b/include/rdma/uverbs_std_types.h
@@ -104,18 +104,20 @@ static inline void uobj_put_write(struct ib_uobject *uobj)
104 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); 104 rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
105} 105}
106 106
107static inline int __must_check uobj_alloc_commit(struct ib_uobject *uobj) 107static inline int __must_check
108uobj_alloc_commit(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs)
108{ 109{
109 int ret = rdma_alloc_commit_uobject(uobj); 110 int ret = rdma_alloc_commit_uobject(uobj, attrs);
110 111
111 if (ret) 112 if (ret)
112 return ret; 113 return ret;
113 return 0; 114 return 0;
114} 115}
115 116
116static inline void uobj_alloc_abort(struct ib_uobject *uobj) 117static inline void uobj_alloc_abort(struct ib_uobject *uobj,
118 struct uverbs_attr_bundle *attrs)
117{ 119{
118 rdma_alloc_abort_uobject(uobj); 120 rdma_alloc_abort_uobject(uobj, attrs);
119} 121}
120 122
121static inline struct ib_uobject * 123static inline struct ib_uobject *
diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h
index b68f1b92c25d..d57a5ba00c74 100644
--- a/include/rdma/uverbs_types.h
+++ b/include/rdma/uverbs_types.h
@@ -95,7 +95,8 @@ struct uverbs_obj_type_class {
95 void (*lookup_put)(struct ib_uobject *uobj, enum rdma_lookup_mode mode); 95 void (*lookup_put)(struct ib_uobject *uobj, enum rdma_lookup_mode mode);
96 /* This does not consume the kref on uobj */ 96 /* This does not consume the kref on uobj */
97 int __must_check (*destroy_hw)(struct ib_uobject *uobj, 97 int __must_check (*destroy_hw)(struct ib_uobject *uobj,
98 enum rdma_remove_reason why); 98 enum rdma_remove_reason why,
99 struct uverbs_attr_bundle *attrs);
99 void (*remove_handle)(struct ib_uobject *uobj); 100 void (*remove_handle)(struct ib_uobject *uobj);
100 u8 needs_kfree_rcu; 101 u8 needs_kfree_rcu;
101}; 102};
@@ -126,7 +127,8 @@ struct uverbs_obj_idr_type {
126 * completely unchanged. 127 * completely unchanged.
127 */ 128 */
128 int __must_check (*destroy_object)(struct ib_uobject *uobj, 129 int __must_check (*destroy_object)(struct ib_uobject *uobj,
129 enum rdma_remove_reason why); 130 enum rdma_remove_reason why,
131 struct uverbs_attr_bundle *attrs);
130}; 132};
131 133
132struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj, 134struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
@@ -138,8 +140,10 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj,
138struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj, 140struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
139 struct ib_uverbs_file *ufile, 141 struct ib_uverbs_file *ufile,
140 struct uverbs_attr_bundle *attrs); 142 struct uverbs_attr_bundle *attrs);
141void rdma_alloc_abort_uobject(struct ib_uobject *uobj); 143void rdma_alloc_abort_uobject(struct ib_uobject *uobj,
142int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj); 144 struct uverbs_attr_bundle *attrs);
145int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj,
146 struct uverbs_attr_bundle *attrs);
143 147
144struct uverbs_obj_fd_type { 148struct uverbs_obj_fd_type {
145 /* 149 /*