From: Jens Axboe <axboe@kernel.dk>
To: stable@vger.kernel.org
Subject: [PATCH 6.18.y 3/9] io_uring/sqpoll: don't set IO_SQ_THREAD_SHOULD_STOP on thread exit
Date: Sat, 7 Nov 2026 09:16:28 -0700 [thread overview]
Message-ID: <20261107161634.2500557-4-axboe@kernel.dk> (raw)
In-Reply-To: <20261107161634.2500557-1-axboe@kernel.dk>
From: Shuai Liu <847807867@qq.com>
Commit fca3ff9e2eee7d285585daf51942e0b5e2be354a upstream.
io_sq_thread_stop() carries a WARN_ON_ONCE() asserting that
IO_SQ_THREAD_SHOULD_STOP isn't set yet, i.e. that stopping the SQPOLL
thread is never attempted twice. Since commit 22d9db9fd64a
("io_uring/sqpoll: don't attach to a thread that is canceling"), the
SQPOLL thread itself sets that bit on its way out, so that
io_sq_offload_create() won't attach a new ring to a thread that is
canceling.
When the thread exits on a fatal signal, the bit is thus set before the
ring teardown gets to io_sq_thread_stop(), which now triggers the
warning on every such exit:
WARNING: io_uring/sqpoll.c:88 at io_sq_thread_stop
Workqueue: iou_exit io_ring_exit_work
Call Trace:
io_put_sq_data
io_sq_thread_finish
io_ring_ctx_free
io_ring_exit_work
Introduce a separate IO_SQ_THREAD_EXITING bit for the thread marking
itself as on its way out, and check it in io_sq_offload_create() along
with IO_SQ_THREAD_SHOULD_STOP. IO_SQ_THREAD_SHOULD_STOP regains its
original meaning, "a stop has been requested", and the WARN_ON_ONCE()
holds again.
Reproduced with an SQPOLL ring and an immediate fatal signal: the
warning fires on v7.3.0+ (22d9db9fd64a present) and is gone with this
change.
Reported-by: syzbot+675af112519ca34f5502@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=675af112519ca34f5502
Fixes: 22d9db9fd64a ("io_uring/sqpoll: don't attach to a thread that is canceling")
Signed-off-by: Shuai Liu <847807867@qq.com>
Link: https://patch.msgid.link/tencent_BB08960D79E0261B5C1EB1E589787734E907@qq.com
[axboe: trim excessive comment]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
io_uring/sqpoll.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index 1c7f84192c0a..1d31a4b1a9aa 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -28,6 +28,7 @@
enum {
IO_SQ_THREAD_SHOULD_STOP = 0,
IO_SQ_THREAD_SHOULD_PARK,
+ IO_SQ_THREAD_EXITING,
};
void io_sq_thread_unpark(struct io_sq_data *sqd)
@@ -441,9 +442,10 @@ static int io_sq_thread(void *data)
/*
* Cancelation drops sqd->lock while it waits, and a ring could attach
* to a thread that is on its way out. A fatal signal doesn't set the
- * bit, so set it here for io_sq_offload_create() to see.
+ * stop bit, so mark the thread as exiting here for
+ * io_sq_offload_create() to see.
*/
- set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state);
+ set_bit(IO_SQ_THREAD_EXITING, &sqd->state);
io_uring_cancel_generic(true, sqd);
rcu_assign_pointer(sqd->thread, NULL);
put_task_struct(current);
@@ -514,7 +516,8 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
/* don't attach to a dying SQPOLL thread, would be racy */
ret = 0;
if (attached && (!sqd->thread ||
- test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state)))
+ test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state) ||
+ test_bit(IO_SQ_THREAD_EXITING, &sqd->state)))
ret = -ENXIO;
io_sq_thread_unpark(sqd);
--
2.56.0
next prev parent reply other threads:[~2026-11-07 16:16 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 16:16 [PATCH 6.18.y 0/9] io_uring fixes for 6.18-stable Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 1/9] io_uring/cancel: drop sqd->lock while SQPOLL waits Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 2/9] io_uring/sqpoll: don't attach to a thread that is canceling Jens Axboe
2026-11-07 16:16 ` Jens Axboe [this message]
2026-11-07 16:16 ` [PATCH 6.18.y 4/9] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 5/9] io_uring/cancel: count all requests that a CANCEL_ALL cancels Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 6/9] io_uring/poll: cancel all matching requests in one pass Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 7/9] io_uring/poll: don't poll a writer for a read side hangup Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 8/9] io_uring/poll: don't poll a writer for urgent data Jens Axboe
2026-11-07 16:16 ` [PATCH 6.18.y 9/9] io_uring/rsrc: hold uring_lock across index-alloc put_user Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261107161634.2500557-4-axboe@kernel.dk \
--to=axboe@kernel.dk \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.