diff options
author | Vlastimil Babka <vbabka@suse.cz> | 2025-04-23 10:21:29 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-04-23 09:04:56 -0700 |
commit | 82efd569a8909f2b13140c1b3de88535aea0b051 (patch) | |
tree | 802016c7b33648656021002a6963356f9e488789 /rust/helpers/io.c | |
parent | 0251ddbffbeb213f0f74ef94b2cacce580eb8d76 (diff) | |
download | linux-82efd569a8909f2b13140c1b3de88535aea0b051.tar.gz linux-82efd569a8909f2b13140c1b3de88535aea0b051.tar.bz2 linux-82efd569a8909f2b13140c1b3de88535aea0b051.zip |
locking/local_lock: fix _Generic() matching of local_trylock_t
Michael Larabel reported [1] a nginx performance regression in v6.15-rc3
and bisected it to commit 51339d99c013 ("locking/local_lock, mm: replace
localtry_ helpers with local_trylock_t type")
The problem is the _Generic() usage with a default association that
masks the fact that "local_trylock_t *" association is not being
selected as expected. Replacing the default with the only other
expected type "local_lock_t *" reveals the underlying problem:
include/linux/local_lock_internal.h:174:26: error: ‘_Generic’ selector of type ‘__seg_gs local_lock_t *’ is not compatible with any association
The local_locki's are part of __percpu structures and thus the __percpu
attribute is needed to associate the type properly. Add the attribute
and keep the default replaced to turn any further mismatches into
compile errors.
The failure to recognize local_try_lock_t in __local_lock_release()
means that a local_trylock[_irqsave]() operation will set tl->acquired
to 1 (there's no _Generic() part in the trylock code), but then
local_unlock[_irqrestore]() will not set tl->acquired back to 0, so
further trylock operations will always fail on the same cpu+lock, while
non-trylock operations continue to work - a lockdep_assert() is also not
being executed in the _Generic() part of local_lock() code.
This means consume_stock() and refill_stock() operations will fail
deterministically, resulting in taking the slow paths and worse
performance.
Fixes: 51339d99c013 ("locking/local_lock, mm: replace localtry_ helpers with local_trylock_t type")
Reported-by: Michael Larabel <Michael@phoronix.com>
Closes: https://www.phoronix.com/review/linux-615-nginx-regression/2 [1]
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'rust/helpers/io.c')
0 files changed, 0 insertions, 0 deletions