Skip to content

Commit 81f8f74

Browse files
msanallarleon
authored andcommitted
RDMA/uverbs: Propagate errors from rdma_lookup_get_uobject()
Currently, the IB uverbs API calls uobj_get_uobj_read(), which in turn uses the rdma_lookup_get_uobject() helper to retrieve user objects. In case of failure, uobj_get_uobj_read() returns NULL, overriding the error code from rdma_lookup_get_uobject(). The IB uverbs API then translates this NULL to -EINVAL, masking the actual error and complicating debugging. For example, applications calling ibv_modify_qp that fails with EBUSY when retrieving the QP uobject will see the overridden error code EINVAL instead, masking the actual error. Furthermore, based on rdma-core commit: "2a22f1ced5f3 ("Merge pull request #1568 from jakemoroni/master")" Kernel's IB uverbs return values are either ignored and passed on as is to application or overridden with other errnos in a few cases. Thus, to improve error reporting and debuggability, propagate the original error from rdma_lookup_get_uobject() instead of replacing it with EINVAL. Signed-off-by: Maher Sanalla <msanalla@nvidia.com> Link: https://patch.msgid.link/64f9d3711b183984e939962c2f83383904f97dfb.1740577869.git.leon@kernel.org Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent bee35b7 commit 81f8f74

2 files changed

Lines changed: 77 additions & 69 deletions

File tree

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 76 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,8 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
735735
goto err_free;
736736

737737
pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs);
738-
if (!pd) {
739-
ret = -EINVAL;
738+
if (IS_ERR(pd)) {
739+
ret = PTR_ERR(pd);
740740
goto err_free;
741741
}
742742

@@ -826,8 +826,8 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
826826
if (cmd.flags & IB_MR_REREG_PD) {
827827
new_pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle,
828828
attrs);
829-
if (!new_pd) {
830-
ret = -EINVAL;
829+
if (IS_ERR(new_pd)) {
830+
ret = PTR_ERR(new_pd);
831831
goto put_uobjs;
832832
}
833833
} else {
@@ -936,8 +936,8 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs)
936936
return PTR_ERR(uobj);
937937

938938
pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs);
939-
if (!pd) {
940-
ret = -EINVAL;
939+
if (IS_ERR(pd)) {
940+
ret = PTR_ERR(pd);
941941
goto err_free;
942942
}
943943

@@ -1144,8 +1144,8 @@ static int ib_uverbs_resize_cq(struct uverbs_attr_bundle *attrs)
11441144
return ret;
11451145

11461146
cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs);
1147-
if (!cq)
1148-
return -EINVAL;
1147+
if (IS_ERR(cq))
1148+
return PTR_ERR(cq);
11491149

11501150
ret = cq->device->ops.resize_cq(cq, cmd.cqe, &attrs->driver_udata);
11511151
if (ret)
@@ -1206,8 +1206,8 @@ static int ib_uverbs_poll_cq(struct uverbs_attr_bundle *attrs)
12061206
return ret;
12071207

12081208
cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs);
1209-
if (!cq)
1210-
return -EINVAL;
1209+
if (IS_ERR(cq))
1210+
return PTR_ERR(cq);
12111211

12121212
/* we copy a struct ib_uverbs_poll_cq_resp to user space */
12131213
header_ptr = attrs->ucore.outbuf;
@@ -1255,8 +1255,8 @@ static int ib_uverbs_req_notify_cq(struct uverbs_attr_bundle *attrs)
12551255
return ret;
12561256

12571257
cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs);
1258-
if (!cq)
1259-
return -EINVAL;
1258+
if (IS_ERR(cq))
1259+
return PTR_ERR(cq);
12601260

12611261
ib_req_notify_cq(cq, cmd.solicited_only ?
12621262
IB_CQ_SOLICITED : IB_CQ_NEXT_COMP);
@@ -1338,8 +1338,8 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
13381338
ind_tbl = uobj_get_obj_read(rwq_ind_table,
13391339
UVERBS_OBJECT_RWQ_IND_TBL,
13401340
cmd->rwq_ind_tbl_handle, attrs);
1341-
if (!ind_tbl) {
1342-
ret = -EINVAL;
1341+
if (IS_ERR(ind_tbl)) {
1342+
ret = PTR_ERR(ind_tbl);
13431343
goto err_put;
13441344
}
13451345

@@ -1377,8 +1377,10 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
13771377
if (cmd->is_srq) {
13781378
srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ,
13791379
cmd->srq_handle, attrs);
1380-
if (!srq || srq->srq_type == IB_SRQT_XRC) {
1381-
ret = -EINVAL;
1380+
if (IS_ERR(srq) ||
1381+
srq->srq_type == IB_SRQT_XRC) {
1382+
ret = IS_ERR(srq) ? PTR_ERR(srq) :
1383+
-EINVAL;
13821384
goto err_put;
13831385
}
13841386
}
@@ -1388,23 +1390,29 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
13881390
rcq = uobj_get_obj_read(
13891391
cq, UVERBS_OBJECT_CQ,
13901392
cmd->recv_cq_handle, attrs);
1391-
if (!rcq) {
1392-
ret = -EINVAL;
1393+
if (IS_ERR(rcq)) {
1394+
ret = PTR_ERR(rcq);
13931395
goto err_put;
13941396
}
13951397
}
13961398
}
13971399
}
13981400

1399-
if (has_sq)
1401+
if (has_sq) {
14001402
scq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ,
14011403
cmd->send_cq_handle, attrs);
1404+
if (IS_ERR(scq)) {
1405+
ret = PTR_ERR(scq);
1406+
goto err_put;
1407+
}
1408+
}
1409+
14021410
if (!ind_tbl && cmd->qp_type != IB_QPT_XRC_INI)
14031411
rcq = rcq ?: scq;
14041412
pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd->pd_handle,
14051413
attrs);
1406-
if (!pd || (!scq && has_sq)) {
1407-
ret = -EINVAL;
1414+
if (IS_ERR(pd)) {
1415+
ret = PTR_ERR(pd);
14081416
goto err_put;
14091417
}
14101418

@@ -1499,18 +1507,18 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
14991507
err_put:
15001508
if (!IS_ERR(xrcd_uobj))
15011509
uobj_put_read(xrcd_uobj);
1502-
if (pd)
1510+
if (!IS_ERR_OR_NULL(pd))
15031511
uobj_put_obj_read(pd);
1504-
if (scq)
1512+
if (!IS_ERR_OR_NULL(scq))
15051513
rdma_lookup_put_uobject(&scq->uobject->uevent.uobject,
15061514
UVERBS_LOOKUP_READ);
1507-
if (rcq && rcq != scq)
1515+
if (!IS_ERR_OR_NULL(rcq) && rcq != scq)
15081516
rdma_lookup_put_uobject(&rcq->uobject->uevent.uobject,
15091517
UVERBS_LOOKUP_READ);
1510-
if (srq)
1518+
if (!IS_ERR_OR_NULL(srq))
15111519
rdma_lookup_put_uobject(&srq->uobject->uevent.uobject,
15121520
UVERBS_LOOKUP_READ);
1513-
if (ind_tbl)
1521+
if (!IS_ERR_OR_NULL(ind_tbl))
15141522
uobj_put_obj_read(ind_tbl);
15151523

15161524
uobj_alloc_abort(&obj->uevent.uobject, attrs);
@@ -1672,8 +1680,8 @@ static int ib_uverbs_query_qp(struct uverbs_attr_bundle *attrs)
16721680
}
16731681

16741682
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs);
1675-
if (!qp) {
1676-
ret = -EINVAL;
1683+
if (IS_ERR(qp)) {
1684+
ret = PTR_ERR(qp);
16771685
goto out;
16781686
}
16791687

@@ -1778,8 +1786,8 @@ static int modify_qp(struct uverbs_attr_bundle *attrs,
17781786

17791787
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd->base.qp_handle,
17801788
attrs);
1781-
if (!qp) {
1782-
ret = -EINVAL;
1789+
if (IS_ERR(qp)) {
1790+
ret = PTR_ERR(qp);
17831791
goto out;
17841792
}
17851793

@@ -2045,8 +2053,8 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs)
20452053
return -ENOMEM;
20462054

20472055
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs);
2048-
if (!qp) {
2049-
ret = -EINVAL;
2056+
if (IS_ERR(qp)) {
2057+
ret = PTR_ERR(qp);
20502058
goto out;
20512059
}
20522060

@@ -2083,9 +2091,9 @@ static int ib_uverbs_post_send(struct uverbs_attr_bundle *attrs)
20832091

20842092
ud->ah = uobj_get_obj_read(ah, UVERBS_OBJECT_AH,
20852093
user_wr->wr.ud.ah, attrs);
2086-
if (!ud->ah) {
2094+
if (IS_ERR(ud->ah)) {
2095+
ret = PTR_ERR(ud->ah);
20872096
kfree(ud);
2088-
ret = -EINVAL;
20892097
goto out_put;
20902098
}
20912099
ud->remote_qpn = user_wr->wr.ud.remote_qpn;
@@ -2322,8 +2330,8 @@ static int ib_uverbs_post_recv(struct uverbs_attr_bundle *attrs)
23222330
return PTR_ERR(wr);
23232331

23242332
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs);
2325-
if (!qp) {
2326-
ret = -EINVAL;
2333+
if (IS_ERR(qp)) {
2334+
ret = PTR_ERR(qp);
23272335
goto out;
23282336
}
23292337

@@ -2373,8 +2381,8 @@ static int ib_uverbs_post_srq_recv(struct uverbs_attr_bundle *attrs)
23732381
return PTR_ERR(wr);
23742382

23752383
srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, attrs);
2376-
if (!srq) {
2377-
ret = -EINVAL;
2384+
if (IS_ERR(srq)) {
2385+
ret = PTR_ERR(srq);
23782386
goto out;
23792387
}
23802388

@@ -2430,8 +2438,8 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs)
24302438
}
24312439

24322440
pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs);
2433-
if (!pd) {
2434-
ret = -EINVAL;
2441+
if (IS_ERR(pd)) {
2442+
ret = PTR_ERR(pd);
24352443
goto err;
24362444
}
24372445

@@ -2500,8 +2508,8 @@ static int ib_uverbs_attach_mcast(struct uverbs_attr_bundle *attrs)
25002508
return ret;
25012509

25022510
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs);
2503-
if (!qp)
2504-
return -EINVAL;
2511+
if (IS_ERR(qp))
2512+
return PTR_ERR(qp);
25052513

25062514
obj = qp->uobject;
25072515

@@ -2550,8 +2558,8 @@ static int ib_uverbs_detach_mcast(struct uverbs_attr_bundle *attrs)
25502558
return ret;
25512559

25522560
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs);
2553-
if (!qp)
2554-
return -EINVAL;
2561+
if (IS_ERR(qp))
2562+
return PTR_ERR(qp);
25552563

25562564
obj = qp->uobject;
25572565
mutex_lock(&obj->mcast_lock);
@@ -2685,8 +2693,8 @@ static int kern_spec_to_ib_spec_action(struct uverbs_attr_bundle *attrs,
26852693
UVERBS_OBJECT_FLOW_ACTION,
26862694
kern_spec->action.handle,
26872695
attrs);
2688-
if (!ib_spec->action.act)
2689-
return -EINVAL;
2696+
if (IS_ERR(ib_spec->action.act))
2697+
return PTR_ERR(ib_spec->action.act);
26902698
ib_spec->action.size =
26912699
sizeof(struct ib_flow_spec_action_handle);
26922700
flow_resources_add(uflow_res,
@@ -2703,8 +2711,8 @@ static int kern_spec_to_ib_spec_action(struct uverbs_attr_bundle *attrs,
27032711
UVERBS_OBJECT_COUNTERS,
27042712
kern_spec->flow_count.handle,
27052713
attrs);
2706-
if (!ib_spec->flow_count.counters)
2707-
return -EINVAL;
2714+
if (IS_ERR(ib_spec->flow_count.counters))
2715+
return PTR_ERR(ib_spec->flow_count.counters);
27082716
ib_spec->flow_count.size =
27092717
sizeof(struct ib_flow_spec_action_count);
27102718
flow_resources_add(uflow_res,
@@ -2922,14 +2930,14 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
29222930
return PTR_ERR(obj);
29232931

29242932
pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, attrs);
2925-
if (!pd) {
2926-
err = -EINVAL;
2933+
if (IS_ERR(pd)) {
2934+
err = PTR_ERR(pd);
29272935
goto err_uobj;
29282936
}
29292937

29302938
cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs);
2931-
if (!cq) {
2932-
err = -EINVAL;
2939+
if (IS_ERR(cq)) {
2940+
err = PTR_ERR(cq);
29332941
goto err_put_pd;
29342942
}
29352943

@@ -3030,8 +3038,8 @@ static int ib_uverbs_ex_modify_wq(struct uverbs_attr_bundle *attrs)
30303038
return -EINVAL;
30313039

30323040
wq = uobj_get_obj_read(wq, UVERBS_OBJECT_WQ, cmd.wq_handle, attrs);
3033-
if (!wq)
3034-
return -EINVAL;
3041+
if (IS_ERR(wq))
3042+
return PTR_ERR(wq);
30353043

30363044
if (cmd.attr_mask & IB_WQ_FLAGS) {
30373045
wq_attr.flags = cmd.flags;
@@ -3114,8 +3122,8 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs)
31143122
num_read_wqs++) {
31153123
wq = uobj_get_obj_read(wq, UVERBS_OBJECT_WQ,
31163124
wqs_handles[num_read_wqs], attrs);
3117-
if (!wq) {
3118-
err = -EINVAL;
3125+
if (IS_ERR(wq)) {
3126+
err = PTR_ERR(wq);
31193127
goto put_wqs;
31203128
}
31213129

@@ -3270,8 +3278,8 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs)
32703278
}
32713279

32723280
qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs);
3273-
if (!qp) {
3274-
err = -EINVAL;
3281+
if (IS_ERR(qp)) {
3282+
err = PTR_ERR(qp);
32753283
goto err_uobj;
32763284
}
32773285

@@ -3417,15 +3425,15 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
34173425
if (ib_srq_has_cq(cmd->srq_type)) {
34183426
attr.ext.cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ,
34193427
cmd->cq_handle, attrs);
3420-
if (!attr.ext.cq) {
3421-
ret = -EINVAL;
3428+
if (IS_ERR(attr.ext.cq)) {
3429+
ret = PTR_ERR(attr.ext.cq);
34223430
goto err_put_xrcd;
34233431
}
34243432
}
34253433

34263434
pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd->pd_handle, attrs);
3427-
if (!pd) {
3428-
ret = -EINVAL;
3435+
if (IS_ERR(pd)) {
3436+
ret = PTR_ERR(pd);
34293437
goto err_put_cq;
34303438
}
34313439

@@ -3532,8 +3540,8 @@ static int ib_uverbs_modify_srq(struct uverbs_attr_bundle *attrs)
35323540
return ret;
35333541

35343542
srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, attrs);
3535-
if (!srq)
3536-
return -EINVAL;
3543+
if (IS_ERR(srq))
3544+
return PTR_ERR(srq);
35373545

35383546
attr.max_wr = cmd.max_wr;
35393547
attr.srq_limit = cmd.srq_limit;
@@ -3560,8 +3568,8 @@ static int ib_uverbs_query_srq(struct uverbs_attr_bundle *attrs)
35603568
return ret;
35613569

35623570
srq = uobj_get_obj_read(srq, UVERBS_OBJECT_SRQ, cmd.srq_handle, attrs);
3563-
if (!srq)
3564-
return -EINVAL;
3571+
if (IS_ERR(srq))
3572+
return PTR_ERR(srq);
35653573

35663574
ret = ib_query_srq(srq, &attr);
35673575

@@ -3686,8 +3694,8 @@ static int ib_uverbs_ex_modify_cq(struct uverbs_attr_bundle *attrs)
36863694
return -EOPNOTSUPP;
36873695

36883696
cq = uobj_get_obj_read(cq, UVERBS_OBJECT_CQ, cmd.cq_handle, attrs);
3689-
if (!cq)
3690-
return -EINVAL;
3697+
if (IS_ERR(cq))
3698+
return PTR_ERR(cq);
36913699

36923700
ret = rdma_set_cq_moderation(cq, cmd.attr.cq_count, cmd.attr.cq_period);
36933701

include/rdma/uverbs_std_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
3535
{
3636
if (IS_ERR(uobj))
37-
return NULL;
37+
return ERR_CAST(uobj);
3838
return uobj->object;
3939
}
4040
#define uobj_get_obj_read(_object, _type, _id, _attrs) \

0 commit comments

Comments
 (0)