summaryrefslogtreecommitdiff
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
authorNguyen Ngoc Thang <ngocthang2710.1999@gmail.com>2026-10-14 22:43:41 +0700
committerTejun Heo <tj@kernel.org>2026-10-14 07:03:54 -1000
commitbda345b3fc59f2899c50379c64a0734a3e720683 (patch)
treebf494e8707e818ad9c5b69ab15c920e50bc1c7af /kernel/workqueue.c
parent9d4815c14f7faf789aeaa63515024168daf0390c (diff)
workqueue: mark pool->nr_running as __data_racy
wq_worker_running() increments pool->nr_running with only preemption disabled, while kick_pool_pick() reads it via need_more_worker() under pool->lock, so the two can run concurrently on different CPUs. KCSAN reports: BUG: KCSAN: data-race in kick_pool_pick / wq_worker_running write to 0xffff888059c2af24 of 4 bytes by task 3007 on cpu 0: wq_worker_running+0x114/0x130 schedule_timeout+0x16e/0x180 io_schedule_timeout+0x4c/0x70 submit_bio_wait+0xd7/0x110 blkdev_issue_flush+0x4c/0x70 ext4_sync_file+0x60d/0x6c0 aio_fsync_work+0x7f/0x270 process_one_work+0x4ae/0xa00 read to 0xffff888059c2af24 of 4 bytes by task 3001 on cpu 1: kick_pool_pick+0x7a/0x3a0 __queue_work+0x72d/0xcf0 queue_work_on+0x9d/0xb0 schedule_on_each_cpu+0x11a/0x2d0 vmstat_refresh+0x23/0x140 proc_sys_call_handler+0x2b9/0x4f0 The race is benign. The increment in wq_worker_running() is the only lockless write to nr_running; decrements and the reset are done under pool->lock, so a reader holding the lock sees either the old or the new count. A stale 0 costs at most a spurious wakeup of an idle worker. A nonzero count is correct because the incrementing worker is running and re-checks the worklist under pool->lock before it stops counting. The increment can also go 1 -> 2, e.g. when a worker sleeping in a work item wakes up after kick_pool() woke another worker. The lockless increment is part of how nr_running is designed to work, as the comment above the field documents. Mark the field __data_racy so that every reader is covered, not just need_more_worker(). Reported-by: syzbot+8922e6b8343f70be92e8@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8922e6b8343f70be92e8 Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index e618108c6127..41754f4126a6 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -212,7 +212,7 @@ struct worker_pool {
* but w/ pool->lock held. The readers grab pool->lock and are
* guaranteed to see if the counter reached zero.
*/
- int nr_running;
+ int __data_racy nr_running;
struct list_head worklist; /* L: list of pending works */