mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
nfsd: add missing read barrier to rpc_status_get dumpit seqcount retry
The hand-rolled seqcount-like protocol in nfsd_nl_rpc_status_get_dumpit()
is missing a read memory barrier (smp_rmb) before its second counter
check. The standard kernel read_seqcount_retry() includes smp_rmb()
to ensure that all data reads complete before the counter is re-checked.
Without this barrier, on weakly-ordered architectures (ARM, POWER),
the CPU may reorder field reads past the second counter check, making
the retry logic ineffective: it could observe a consistent counter pair
while reading fields that have been concurrently modified by the writer.
Add smp_rmb() before the second counter check to order the field reads
ahead of it, matching the barrier semantics of the standard seqcount
read-side. The begin-side smp_load_acquire() already pairs with the
smp_store_release() in nfsd_dispatch(); with the smp_rmb() now ordering
the field reads, the retry check no longer needs acquire semantics and
reads the counter with a plain READ_ONCE(), as read_seqcount_retry()
does.
Fixes: bd9d6a3efa ("NFSD: add rpc_status netlink support")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jeff Layton <jlayton@kernel.org>
[ cel: Use READ_ONCE instead of smp_load_acquire() ]
Link: https://patch.msgid.link/20260611-nfsd-testing-v2-2-5b90e276f2d9@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
This commit is contained in:
parent
ae4c38555e
commit
a71f161a85
|
|
@ -1576,11 +1576,14 @@ int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
|
|||
#endif /* CONFIG_NFSD_V4 */
|
||||
|
||||
/*
|
||||
* Acquire rq_status_counter before reporting the rqst
|
||||
* fields to the user.
|
||||
* Read-side load-load fence: order the field reads
|
||||
* above before the counter re-read below, mirroring
|
||||
* the smp_rmb() in the standard seqcount retry. The
|
||||
* begin-side smp_load_acquire() above pairs with the
|
||||
* smp_store_release() in nfsd_dispatch().
|
||||
*/
|
||||
if (smp_load_acquire(&rqstp->rq_status_counter) !=
|
||||
status_counter)
|
||||
smp_rmb();
|
||||
if (READ_ONCE(rqstp->rq_status_counter) != status_counter)
|
||||
continue;
|
||||
|
||||
ret = nfsd_genl_rpc_status_compose_msg(skb, cb,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user