From: Lei Feng Date: Thu, 30 Jun 2022 02:46:31 +0000 (+0800) Subject: LU-15986 ptlrpc: protect rq_repmsg in ptlrpc_req_drop_rs() X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=a52a345de124934f3c24216e454db4a94509e6be;p=fs%2Flustre-release.git LU-15986 ptlrpc: protect rq_repmsg in ptlrpc_req_drop_rs() There is a race condition that: on server side, one thread sent early replay and is deleting the reply message, another is searching for existing request and print some debug information in _debug_req() if there is a duplicated request. They both operate on req->rq_repmsg but it is not protected in ptlrpc_req_drop_rs(). So we protected it with req->rq_early_free_lock. Lustre-change: https://review.whamcloud.com/47839 Lustre-commit: aaef545cff2dd958418ec9fb364d4bbe1408edb9 Signed-off-by: Lei Feng Change-Id: Ied55427ee15c3ef84bdd2d579844eba398dbf010 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/47860 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h index daea1bd..1d94c3e 100644 --- a/lustre/include/lustre_net.h +++ b/lustre/include/lustre_net.h @@ -2487,11 +2487,18 @@ ptlrpc_rs_decref(struct ptlrpc_reply_state *rs) /* Should only be called once per req */ static inline void ptlrpc_req_drop_rs(struct ptlrpc_request *req) { - if (req->rq_reply_state == NULL) - return; /* shouldn't occur */ - ptlrpc_rs_decref(req->rq_reply_state); - req->rq_reply_state = NULL; - req->rq_repmsg = NULL; + if (req->rq_reply_state == NULL) + return; /* shouldn't occur */ + + /* req_repmsg equals rq_reply_state->rs_msg, + * so set it to NULL before rq_reply_state is possibly freed + */ + spin_lock(&req->rq_early_free_lock); + req->rq_repmsg = NULL; + spin_unlock(&req->rq_early_free_lock); + + ptlrpc_rs_decref(req->rq_reply_state); + req->rq_reply_state = NULL; } static inline __u32 lustre_request_magic(struct ptlrpc_request *req) diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 8a48bcd..5d8d257 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -1449,6 +1449,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) GOTO(out_free, rc = -ENOMEM); *reqcopy = *req; + spin_lock_init(&reqcopy->rq_early_free_lock); reqcopy->rq_reply_state = NULL; reqcopy->rq_rep_swab_mask = 0; reqcopy->rq_pack_bulk = 0;