Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rqspinlock: Fix TAS fallback lock entry creation

The TAS fallback can be invoked directly when queued spin locks are
disabled, and through the slow path when paravirt is enabled for queued
spin locks. In the latter case, the res_spin_lock macro will attempt the
fast path and already hold the entry when entering the slow path. This
will lead to creation of extraneous entries that are not released, which
may cause false positives for deadlock detection.

Fix this by always preceding invocation of the TAS fallback in every
case with the grabbing of the held lock entry, and add a comment to make
note of this.

Fixes: c9102a68c070 ("rqspinlock: Add a test-and-set fallback")
Reported-by: Amery Hung <ameryhung@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Tested-by: Amery Hung <ameryhung@gmail.com>
Link: https://lore.kernel.org/r/20260122115911.3668985-1-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
82f3b142 a32ae265

+5 -4
+1 -1
include/asm-generic/rqspinlock.h
··· 191 191 192 192 #else 193 193 194 - #define res_spin_lock(lock) resilient_tas_spin_lock(lock) 194 + #define res_spin_lock(lock) ({ grab_held_lock_entry(lock); resilient_tas_spin_lock(lock); }) 195 195 196 196 #endif /* CONFIG_QUEUED_SPINLOCKS */ 197 197
+4 -3
kernel/bpf/rqspinlock.c
··· 265 265 266 266 RES_INIT_TIMEOUT(ts); 267 267 /* 268 - * The fast path is not invoked for the TAS fallback, so we must grab 269 - * the deadlock detection entry here. 268 + * We are either called directly from res_spin_lock after grabbing the 269 + * deadlock detection entry when queued spinlocks are disabled, or from 270 + * resilient_queued_spin_lock_slowpath after grabbing the deadlock 271 + * detection entry. No need to obtain it here. 270 272 */ 271 - grab_held_lock_entry(lock); 272 273 273 274 /* 274 275 * Since the waiting loop's time is dependent on the amount of