Skip to content

Commit 2c96eb7

Browse files
committed
IB/uverbs: Always propagate errors from rdma_alloc_commit_uobject()
The ioctl framework already does this correctly, but the write path did not. This is trivially fixed by simply using a standard pattern to return uobj_alloc_commit() as the last statement in every function. Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent e951747 commit 2c96eb7

File tree

4 files changed

+26
-39
lines changed

4 files changed

+26
-39
lines changed

drivers/infiniband/core/rdma_core.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,10 @@ static void alloc_commit_fd_uobject(struct ib_uobject *uobj)
532532

533533
/*
534534
* In all cases rdma_alloc_commit_uobject() consumes the kref to uobj and the
535-
* caller can no longer assume uobj is valid.
535+
* caller can no longer assume uobj is valid. If this function fails it
536+
* destroys the uboject, including the attached HW object.
536537
*/
537-
int rdma_alloc_commit_uobject(struct ib_uobject *uobj)
538+
int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj)
538539
{
539540
struct ib_uverbs_file *ufile = uobj->ufile;
540541

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
372372
goto err_copy;
373373
}
374374

375-
uobj_alloc_commit(uobj);
376-
377-
return in_len;
375+
return uobj_alloc_commit(uobj, in_len);
378376

379377
err_copy:
380378
ib_dealloc_pd(pd);
@@ -579,9 +577,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
579577

580578
mutex_unlock(&file->device->xrcd_tree_mutex);
581579

582-
uobj_alloc_commit(&obj->uobject);
583-
584-
return in_len;
580+
return uobj_alloc_commit(&obj->uobject, in_len);
585581

586582
err_copy:
587583
if (inode) {
@@ -723,9 +719,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
723719

724720
uobj_put_obj_read(pd);
725721

726-
uobj_alloc_commit(uobj);
727-
728-
return in_len;
722+
return uobj_alloc_commit(uobj, in_len);
729723

730724
err_copy:
731725
ib_dereg_mr(mr);
@@ -901,9 +895,7 @@ ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
901895
}
902896

903897
uobj_put_obj_read(pd);
904-
uobj_alloc_commit(uobj);
905-
906-
return in_len;
898+
return uobj_alloc_commit(uobj, in_len);
907899

908900
err_copy:
909901
uverbs_dealloc_mw(mw);
@@ -959,8 +951,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
959951
return -EFAULT;
960952
}
961953

962-
uobj_alloc_commit(uobj);
963-
return in_len;
954+
return uobj_alloc_commit(uobj, in_len);
964955
}
965956

966957
static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
@@ -1041,7 +1032,9 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
10411032
if (ret)
10421033
goto err_cb;
10431034

1044-
uobj_alloc_commit(&obj->uobject);
1035+
ret = uobj_alloc_commit(&obj->uobject, 0);
1036+
if (ret)
1037+
return ERR_PTR(ret);
10451038
return obj;
10461039

10471040
err_cb:
@@ -1596,9 +1589,7 @@ static int create_qp(struct ib_uverbs_file *file,
15961589
if (ind_tbl)
15971590
uobj_put_obj_read(ind_tbl);
15981591

1599-
uobj_alloc_commit(&obj->uevent.uobject);
1600-
1601-
return 0;
1592+
return uobj_alloc_commit(&obj->uevent.uobject, 0);
16021593
err_cb:
16031594
ib_destroy_qp(qp);
16041595

@@ -1801,10 +1792,7 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
18011792
qp->uobject = &obj->uevent.uobject;
18021793
uobj_put_read(xrcd_uobj);
18031794

1804-
1805-
uobj_alloc_commit(&obj->uevent.uobject);
1806-
1807-
return in_len;
1795+
return uobj_alloc_commit(&obj->uevent.uobject, in_len);
18081796

18091797
err_destroy:
18101798
ib_destroy_qp(qp);
@@ -2607,9 +2595,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
26072595
}
26082596

26092597
uobj_put_obj_read(pd);
2610-
uobj_alloc_commit(uobj);
2611-
2612-
return in_len;
2598+
return uobj_alloc_commit(uobj, in_len);
26132599

26142600
err_copy:
26152601
rdma_destroy_ah(ah);
@@ -3155,8 +3141,7 @@ int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file,
31553141

31563142
uobj_put_obj_read(pd);
31573143
uobj_put_obj_read(cq);
3158-
uobj_alloc_commit(&obj->uevent.uobject);
3159-
return 0;
3144+
return uobj_alloc_commit(&obj->uevent.uobject, 0);
31603145

31613146
err_copy:
31623147
ib_destroy_wq(wq);
@@ -3403,8 +3388,7 @@ int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file,
34033388
for (j = 0; j < num_read_wqs; j++)
34043389
uobj_put_obj_read(wqs[j]);
34053390

3406-
uobj_alloc_commit(uobj);
3407-
return 0;
3391+
return uobj_alloc_commit(uobj, 0);
34083392

34093393
err_copy:
34103394
ib_destroy_rwq_ind_table(rwq_ind_tbl);
@@ -3605,11 +3589,10 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
36053589
goto err_copy;
36063590

36073591
uobj_put_obj_read(qp);
3608-
uobj_alloc_commit(uobj);
36093592
kfree(flow_attr);
36103593
if (cmd.flow_attr.num_of_specs)
36113594
kfree(kern_flow_attr);
3612-
return 0;
3595+
return uobj_alloc_commit(uobj, 0);
36133596
err_copy:
36143597
if (!qp->device->destroy_flow(flow_id))
36153598
atomic_dec(&qp->usecnt);
@@ -3761,9 +3744,7 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
37613744
uobj_put_obj_read(attr.ext.cq);
37623745

37633746
uobj_put_obj_read(pd);
3764-
uobj_alloc_commit(&obj->uevent.uobject);
3765-
3766-
return 0;
3747+
return uobj_alloc_commit(&obj->uevent.uobject, 0);
37673748

37683749
err_copy:
37693750
ib_destroy_srq(srq);

include/rdma/uverbs_std_types.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,14 @@ static inline int __must_check uobj_remove_commit(struct ib_uobject *uobj)
102102
return rdma_remove_commit_uobject(uobj);
103103
}
104104

105-
static inline void uobj_alloc_commit(struct ib_uobject *uobj)
105+
static inline int __must_check uobj_alloc_commit(struct ib_uobject *uobj,
106+
int success_res)
106107
{
107-
rdma_alloc_commit_uobject(uobj);
108+
int ret = rdma_alloc_commit_uobject(uobj);
109+
110+
if (ret)
111+
return ret;
112+
return success_res;
108113
}
109114

110115
static inline void uobj_alloc_abort(struct ib_uobject *uobj)

include/rdma/uverbs_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type,
127127
struct ib_uverbs_file *ufile);
128128
void rdma_alloc_abort_uobject(struct ib_uobject *uobj);
129129
int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj);
130-
int rdma_alloc_commit_uobject(struct ib_uobject *uobj);
130+
int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj);
131131
int rdma_explicit_destroy(struct ib_uobject *uobject);
132132

133133
struct uverbs_obj_fd_type {

0 commit comments

Comments
 (0)