From 68b4780e303976aad3bb4cd02ad483214e1ed33c Mon Sep 17 00:00:00 2001 From: Liang Zhen Date: Fri, 21 Dec 2012 14:27:57 +0800 Subject: [PATCH] LU-2263 ptlrpc: deadlock of obd_import::imp_lock ptlrpc_at_recv_early_reply() calls ptlrpc_at_set_req_timeout() with hold of ptlrpc_request::rq_lock, and ptlrpc_at_set_req_timeout()->import_at_get_index() requires imp_lock, it violates locking-order rule of Lustre, which assumes rq_lock can nest in imp_lock. Signed-off-by: Liang Zhen Change-Id: I924839b59ca1fa1cdf01568872de867ce3985f8b Reviewed-on: http://review.whamcloud.com/4880 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev --- lustre/ptlrpc/client.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index 55818fe..5ebdef3 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -354,27 +354,28 @@ static int ptlrpc_at_recv_early_reply(struct ptlrpc_request *req) sptlrpc_cli_finish_early_reply(early_req); - spin_lock(&req->rq_lock); + if (rc != 0) { + spin_lock(&req->rq_lock); + RETURN(rc); + } - if (rc == 0) { - /* Adjust the local timeout for this req */ - ptlrpc_at_set_req_timeout(req); - - olddl = req->rq_deadline; - /* server assumes it now has rq_timeout from when it sent the - early reply, so client should give it at least that long. */ - req->rq_deadline = cfs_time_current_sec() + req->rq_timeout + - ptlrpc_at_get_net_latency(req); - - DEBUG_REQ(D_ADAPTTO, req, - "Early reply #%d, new deadline in "CFS_DURATION_T"s " - "("CFS_DURATION_T"s)", req->rq_early_count, - cfs_time_sub(req->rq_deadline, - cfs_time_current_sec()), - cfs_time_sub(req->rq_deadline, olddl)); - } + /* Adjust the local timeout for this req */ + ptlrpc_at_set_req_timeout(req); - RETURN(rc); + spin_lock(&req->rq_lock); + olddl = req->rq_deadline; + /* server assumes it now has rq_timeout from when it sent the + * early reply, so client should give it at least that long. */ + req->rq_deadline = cfs_time_current_sec() + req->rq_timeout + + ptlrpc_at_get_net_latency(req); + + DEBUG_REQ(D_ADAPTTO, req, + "Early reply #%d, new deadline in "CFS_DURATION_T"s " + "("CFS_DURATION_T"s)", req->rq_early_count, + cfs_time_sub(req->rq_deadline, cfs_time_current_sec()), + cfs_time_sub(req->rq_deadline, olddl)); + + RETURN(rc); } /** -- 1.8.3.1