From: Jens Axboe <axboe@kernel.dk>
To: stable@vger.kernel.org
Subject: [PATCH 6.6.y 1/7] io_uring/cancel: drop sqd->lock while SQPOLL waits
Date: Sat, 7 Nov 2026 09:15:36 -0700 [thread overview]
Message-ID: <20261107161542.2500190-2-axboe@kernel.dk> (raw)
In-Reply-To: <20261107161542.2500190-1-axboe@kernel.dk>
From: Chris Mason <mason@kernel.org>
Commit cb0306c52ffae083a86fb283de67875ae7a9500e upstream.
An exiting SQPOLL thread calls io_uring_cancel_generic() with sqd->lock
held, and keeps it across cond_resched() and the sleep until nothing is
in flight anymore. A zero-copy send notification can't be canceled and
stays pending as long as the peer doesn't read, so the lock is held for
as long as a user cares to. io_ring_exit_work() needs it to park the
thread, and so do IORING_REGISTER_IOWQ_AFF and IOWQ_MAX_WORKERS. With
64 such rings sharing the thread, every iou_exit slot sleeps on the lock
and no ring gets freed for anyone.
Drop the lock around cond_resched() and the sleep, like the main loop of
the thread does. Each walk of ctx_list is still under one hold, and
nothing is kept across the unlock. The thread drops its io-wq, frees its
tctx and clears sqd->thread under one hold after the loop, so whoever
holds the lock and finds sqd->thread set can still use them.
Fixes: 63809137ebb5 ("io_uring: flush notifiers after sendzc")
Signed-off-by: Chris Mason <mason@kernel.org>
[axboe: adapted to the schedule_timeout() based loop]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[axboe: io_uring_cancel_generic() is in io_uring.c in 6.6, and uses a
schedule() based wait loop]
---
io_uring/io_uring.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
index af349afeb4cb..43860048d2bf 100644
--- a/io_uring/io_uring.c
+++ b/io_uring/io_uring.c
@@ -3566,7 +3566,16 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd)
}
if (loop) {
+ /*
+ * A request that runs in io-wq and doesn't end makes
+ * each round come here. Don't hold sqd->lock for that
+ * long either.
+ */
+ if (sqd)
+ mutex_unlock(&sqd->lock);
cond_resched();
+ if (sqd)
+ mutex_lock(&sqd->lock);
continue;
}
@@ -3584,8 +3593,20 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd)
* avoids a race where a completion comes in before we did
* prepare_to_wait().
*/
- if (inflight == tctx_inflight(tctx, !cancel_all))
+ if (inflight == tctx_inflight(tctx, !cancel_all)) {
+ /*
+ * A zero-copy notification can't be canceled, and a
+ * peer that doesn't read keeps it pending. Don't hold
+ * sqd->lock while waiting for it, or whoever wants the
+ * lock sleeps as long. No ring is used across this,
+ * the next round walks ->ctx_list anew.
+ */
+ if (sqd)
+ mutex_unlock(&sqd->lock);
schedule();
+ if (sqd)
+ mutex_lock(&sqd->lock);
+ }
end_wait:
finish_wait(&tctx->wait, &wait);
} while (1);
--
2.56.0
next prev parent reply other threads:[~2026-11-07 16:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 16:15 [PATCH 6.6.y 0/7] io_uring fixes for 6.6-stable Jens Axboe
2026-11-07 16:15 ` Jens Axboe [this message]
2026-11-07 16:15 ` [PATCH 6.6.y 2/7] io_uring/sqpoll: don't attach to a thread that is canceling Jens Axboe
2026-11-07 16:15 ` [PATCH 6.6.y 3/7] io_uring/sqpoll: don't set IO_SQ_THREAD_SHOULD_STOP on thread exit Jens Axboe
2026-11-07 16:15 ` [PATCH 6.6.y 4/7] io_uring/poll: cancel all matching requests in one pass Jens Axboe
2026-11-07 16:15 ` [PATCH 6.6.y 5/7] io_uring/poll: don't poll a writer for a read side hangup Jens Axboe
2026-11-07 16:15 ` [PATCH 6.6.y 6/7] io_uring/poll: don't poll a writer for urgent data Jens Axboe
2026-11-07 16:15 ` [PATCH 6.6.y 7/7] 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=20261107161542.2500190-2-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.