]> git.hungrycats.org Git - linux/commitdiff
IB/core: Fix deadlock on uverbs modify_qp error flow
authorMoshe Lazer <moshel@mellanox.com>
Thu, 5 Feb 2015 11:53:52 +0000 (13:53 +0200)
committerSasha Levin <sasha.levin@oracle.com>
Tue, 24 Mar 2015 01:02:45 +0000 (21:02 -0400)
commit 0fb8bcf022f19a375d7c4bd79ac513da8ae6d78b upstream.

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>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
drivers/infiniband/core/uverbs_cmd.c

index 5ba2a86aab6a8ac4a5b6f5693b6627d0832a5f6c..63a9f04bdb6cb3e4d7c88c40dbd3fb318076e964 100644 (file)
@@ -2057,20 +2057,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);