Whamcloud - gitweb
LU-15986 ptlrpc: protect rq_repmsg in ptlrpc_req_drop_rs()
authorLei Feng <flei@whamcloud.com>
Thu, 30 Jun 2022 02:46:31 +0000 (10:46 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Tue, 11 Oct 2022 07:47:32 +0000 (07:47 +0000)
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 <flei@whamcloud.com>
Change-Id: Ied55427ee15c3ef84bdd2d579844eba398dbf010
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/47860
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lustre/include/lustre_net.h
lustre/ptlrpc/service.c

index daea1bd..1d94c3e 100644 (file)
@@ -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)
index 8a48bcd..5d8d257 100644 (file)
@@ -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;