From c56452fbb74a70196a9a330ed863653bae306c20 Mon Sep 17 00:00:00 2001 From: Andriy Skulysh Date: Thu, 24 Nov 2022 15:18:04 +0200 Subject: [PATCH] LU-16430 ptlrpc: racy rq_obsolete bit modification Racy bit modification causes assertion failure in ptlrpc_at_remove_timed(): ASSERTION( !list_empty(&req->rq_srv.sr_timed_list) ) rq_obsolete is a bit field, so it's modification isn't atomic and should be modified under rq_lock. Lustre-change: https://review.whamcloud.com/49505 Lustre-commit: 14ac768fd9633c5cf4474555170e5042c71a135b Change-Id: Ib1d3ad189a78b71ecf5b01585478922e984c9568 HPE-bug-id: LUS-11368 Fixes: 23773b32bf ("LU-11444 ptlrpc: resend may corrupt the data") Signed-off-by: Andriy Skulysh Reviewed-by: Alexander Zarochentsev Reviewed-by: Neil Brown Reviewed-by: Oleg Drokin Signed-off-by: Gian-Carlo DeFazio Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52338 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Alexander Boyko --- lustre/include/lustre_net.h | 2 +- lustre/ptlrpc/service.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h index 7fde30c..466aec7 100644 --- a/lustre/include/lustre_net.h +++ b/lustre/include/lustre_net.h @@ -1005,7 +1005,7 @@ struct ptlrpc_request { rq_allow_intr:1; /** @} */ - /** server-side flags @{ */ + /** server-side flags are serialized by rq_lock @{ */ unsigned int rq_hp:1, /**< high priority RPC */ rq_at_linked:1, /**< link into service's srv_at_array */ diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 366dc5a..63c1ac0 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -1673,7 +1673,9 @@ found: #ifdef HAVE_SERVER_SUPPORT static void ptlrpc_server_mark_obsolete(struct ptlrpc_request *req) { + spin_lock(&req->rq_lock); req->rq_obsolete = 1; + spin_unlock(&req->rq_lock); } static void @@ -1860,7 +1862,9 @@ static int ptlrpc_server_request_add(struct ptlrpc_service_part *svcpt, ptlrpc_nrs_req_finalize(req); /* don't mark slot unused for resend in progress */ + spin_lock(&req->rq_lock); req->rq_obsolete = 1; + spin_unlock(&req->rq_lock); RETURN(-EBUSY); } -- 1.8.3.1