linux/kernel/locking
Sun Shaojie c9c8578ad5 locking/percpu-rwsem: Annotate intentional data race in readers_active_check()
KCSAN reports a data race between readers_active_check() and a
concurrently executing reader:

  BUG: KCSAN: data-race in readers_active_check / percpu_down_write

  race at unknown origin, with read to 0xffff9f3eb5bf5f30 of 4 bytes
  by task 1271 on cpu 14:
   readers_active_check+0x...
   percpu_down_write+0x152/0x1f0

  value changed: 0xfffffff9 -> 0xfffffff8

readers_active_check() calls per_cpu_sum(*sem->read_count), which
iterates over all CPUs and reads each CPU's per-CPU read_count
variable.  Concurrently, a reader on a remote CPU is modifying its own
CPU's read_count via this_cpu_inc() / this_cpu_dec() as it enters and
exits the critical section.  These are plain reads and writes to the
same per-CPU storage, hence KCSAN flags a data race.

This race is benign.  readers_active_check() is called from the
percpu_down_write() wait loop (rcuwait_wait_event) after sem->block is
already set.  At this point:

  - New readers must immediately back out (they see block set, decrement
    their counter, and wake the writer), so counters can only decrease.

  - If the sum catches a reader's increment before its decrement,
    readers_active_check() sees a non-zero sum and returns false.  The
    writer merely iterates the wait loop again -- a harmless retry.

  - A false zero (observing sum == 0 while a reader is still active)
    cannot happen: per_cpu_sum() reads each CPU's counter, and each
    per-CPU int read is atomic on all architectures, so an active
    reader's counter is always seen as non-zero.

Annotate the read with data_race() to suppress the KCSAN warning and
document the intentional nature of this unlocked access.

Signed-off-by: Sun Shaojie <sunshaojie@kylinos.cn>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260623104132.505117-1-sunshaojie@kylinos.cn
2026-07-31 10:32:25 +02:00
..
irqflag-debug.c lockdep: Noinstr annotate warn_bogus_irq_restore() 2021-02-10 14:44:39 +01:00
lock_events_list.h bpf_res_spin_lock 2025-03-30 13:06:27 -07:00
lock_events.c locking/debug: Fix debugfs API return value checks to use IS_ERR() 2023-10-03 10:11:25 +02:00
lock_events.h locking/qspinlock: Always evaluate lockevent* non-event parameter once 2024-03-21 20:45:17 +01:00
lockdep_internals.h locking/lockdep: Change 'static const' variables to enum values 2025-07-14 21:57:29 -07:00
lockdep_proc.c locking/lockdep: Avoid struct return in lock_stats() 2025-07-14 21:57:20 -07:00
lockdep_states.h locking/lockdep: Rework FS_RECLAIM annotation 2017-08-10 12:29:03 +02:00
lockdep.c locking/lockdep: Fix NULL pointer dereference in __lock_set_class() 2026-07-31 10:32:24 +02:00
locktorture.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
Makefile locking/rwsem: Add context analysis 2026-03-08 11:06:53 +01:00
mcs_spinlock.h locking: Allow obtaining result of arch_mcs_spin_lock_contended 2025-03-19 08:03:04 -07:00
mutex-debug.c Scheduler changes for v7.1: 2026-04-14 13:33:36 -07:00
mutex.c Scheduler updates for v7.2: 2026-06-15 14:50:18 +05:30
mutex.h Scheduler changes for v7.1: 2026-04-14 13:33:36 -07:00
osq_lock.c locking/osq_lock: Use atomic_try_cmpxchg_release() in osq_unlock() 2024-10-25 10:01:50 +02:00
percpu-rwsem.c locking/percpu-rwsem: Annotate intentional data race in readers_active_check() 2026-07-31 10:32:25 +02:00
qrwlock.c locking: Add __lockfunc to slow path functions 2022-08-19 19:47:51 +02:00
qspinlock_paravirt.h locking/pvqspinlock: Convert fields of 'enum vcpu_state' to uppercase 2024-10-17 21:21:16 -07:00
qspinlock_stat.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157 2019-05-30 11:26:37 -07:00
qspinlock.c locking: Move common qspinlock helpers to a private header 2025-03-19 08:02:29 -07:00
qspinlock.h locking: Move common qspinlock helpers to a private header 2025-03-19 08:02:29 -07:00
rtmutex_api.c Locking updates for v7.2: 2026-06-15 14:21:14 +05:30
rtmutex_common.h locking/rtmutex: Add context analysis 2026-03-08 11:06:53 +01:00
rtmutex.c Locking updates for v7.2: 2026-06-15 14:21:14 +05:30
rwbase_rt.c locking: Add contended_release tracepoint to sleepable locks 2026-06-11 13:41:25 +02:00
rwsem.c locking: Add contended_release tracepoint to sleepable locks 2026-06-11 13:41:25 +02:00
semaphore.c locking: Add contended_release tracepoint to sleepable locks 2026-06-11 13:41:25 +02:00
spinlock_debug.c locking/spinlock/debug: Fix data-race in do_raw_write_lock 2025-10-21 12:31:55 +02:00
spinlock_rt.c locking/rt: Fix the incorrect RCU protection in rt_spin_unlock() 2026-06-21 11:51:13 +02:00
spinlock.c locking: Add lock context annotations in the spinlock implementation 2026-03-16 13:16:50 +01:00
test-ww_mutex.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ww_mutex.h sched/proxy: Remove PROXY_WAKING 2026-06-02 12:26:09 +02:00
ww_rt_mutex.c locking/rtmutex: Add context analysis 2026-03-08 11:06:53 +01:00