summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunyu Xiao <runyu.xiao@seu.edu.cn>2026-05-27 20:22:03 +0300
committerJens Axboe <axboe@kernel.dk>2026-05-28 17:06:22 +0300
commit29bef9934b2521f787bb15dd1985d4c0d12ae02a (patch)
treee28a471d27833479f946487457794a93d238ff29
parentca55f98d6ff1ecb31a07b668a8d105b4e0829c6a (diff)
downloadlinux-29bef9934b2521f787bb15dd1985d4c0d12ae02a.tar.xz
io_uring/io-wq: re-check IO_WQ_BIT_EXIT for each linked work item
commit 10dc95939817 ("io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop") fixed the obvious case where io_worker_handle_work() took one exit-bit snapshot before draining pending work, but the fix stops one level too early. io_worker_handle_work() now re-checks IO_WQ_BIT_EXIT in its outer work run loop, yet it still snapshots that bit once before processing a whole dependent linked-work chain. If io_wq_exit_start() sets IO_WQ_BIT_EXIT after the first linked item has started, the remaining linked items can still reuse stale do_kill = false, skip IO_WQ_WORK_CANCEL, and continue running after exit has begun. Move the check further inside, so it covers linked items too. Note: this is a syzbot special as it loves setting up tons of slow linked work on weird devices like msr that take forever to read, and immediately close the ring. Exit then takes a long time. Fixes: 10dc95939817 ("io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn> Link: https://patch.msgid.link/20260527172203.2043962-1-runyu.xiao@seu.edu.cn Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--io_uring/io-wq.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
index 7a9f94a0ce6f..15b35eb8d1f7 100644
--- a/io_uring/io-wq.c
+++ b/io_uring/io-wq.c
@@ -602,7 +602,6 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
struct io_wq *wq = worker->wq;
do {
- bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
struct io_wq_work *work;
/*
@@ -638,6 +637,7 @@ static void io_worker_handle_work(struct io_wq_acct *acct,
/* handle a whole dependent link */
do {
+ bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state);
struct io_wq_work *next_hashed, *linked;
unsigned int work_flags = atomic_read(&work->flags);
unsigned int hash = __io_wq_is_hashed(work_flags)