summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/uverbs_cmd.c
diff options
context:
space:
mode:
authorMoshe Lazer2015-02-05 12:53:52 +0100
committerRoland Dreier2015-02-18 07:06:42 +0100
commit0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b (patch)
tree93ae49f2d4030a880055fd2392119fec22068dfb /drivers/infiniband/core/uverbs_cmd.c
parentIB/core: When marshaling ucma path from user-space, clear unused fields (diff)
downloadkernel-qcow2-linux-0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b.tar.gz
kernel-qcow2-linux-0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b.tar.xz
kernel-qcow2-linux-0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b.zip
IB/core: Fix deadlock on uverbs modify_qp error flow
The deadlock occurs in __uverbs_modify_qp: we take a lock (idr_read_qp) and in case of failure in ib_resolve_eth_l2_attrs we don't release it (put_qp_read). Fix that. Fixes: ed4c54e5b4ba ("IB/core: Resolve Ethernet L2 addresses when modifying QP") Signed-off-by: Moshe Lazer <moshel@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/core/uverbs_cmd.c')
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index b7943ff16ed3..6c52e72f8d2c 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -2091,20 +2091,21 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
if (qp->real_qp == qp) {
ret = ib_resolve_eth_l2_attrs(qp, attr, &cmd.attr_mask);
if (ret)
- goto out;
+ goto release_qp;
ret = qp->device->modify_qp(qp, attr,
modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
} else {
ret = ib_modify_qp(qp, attr, modify_qp_mask(qp->qp_type, cmd.attr_mask));
}
- put_qp_read(qp);
-
if (ret)
- goto out;
+ goto release_qp;
ret = in_len;
+release_qp:
+ put_qp_read(qp);
+
out:
kfree(attr);