SUNRPC: Fix a backchannel deadlock
authorTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 22 Jul 2015 20:31:17 +0000 (16:31 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Wed, 22 Jul 2015 20:33:59 +0000 (16:33 -0400)
xprt_alloc_bc_request() cannot call xprt_free_bc_request() without
deadlocking, since it already holds the xprt->bc_pa_lock.

Reported-by: Chuck Lever <chuck.lever@oracle.com>
Fixes: 0d2a970d0ae55 ("SUNRPC: Fix a backchannel race")
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
net/sunrpc/backchannel_rqst.c

index 9825ff0f91d6c0bde819105f639cae21883bbfad..5a3b50aec397a81b2b2139c04f8a72ad648996e6 100644 (file)
@@ -240,8 +240,8 @@ static struct rpc_rqst *xprt_alloc_bc_request(struct rpc_xprt *xprt, __be32 xid)
                req = xprt_alloc_bc_req(xprt, GFP_ATOMIC);
                if (!req)
                        goto not_found;
-               /* Note: this 'free' request adds it to xprt->bc_pa_list */
-               xprt_free_bc_request(req);
+               list_add_tail(&req->rq_bc_pa_list, &xprt->bc_pa_list);
+               xprt->bc_alloc_count++;
        }
        req = list_first_entry(&xprt->bc_pa_list, struct rpc_rqst,
                                rq_bc_pa_list);