From: Shang En Sim <sim@shangen.org>
To: Jens Axboe <axboe@kernel.dk>, io-uring@vger.kernel.org
Cc: Shang En Sim <sim@shangen.org>,
Peter Zijlstra <peterz@infradead.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH 0/2] io_uring/cancel: cancel all poll matches in one pass
Date: Fri, 30 Oct 2026 00:03:15 -0500 [thread overview]
Message-ID: <20261030050319.1448530-1-sim@shangen.org> (raw)
IORING_OP_ASYNC_CANCEL with IORING_ASYNC_CANCEL_ALL cancels poll
requests one at a time, and every lookup starts over at the beginning
of the poll hash. Cancelled requests stay hashed until their task work
runs, so each lookup also walks past the ones already cancelled. One
cancel that matches K of N pending polls costs about K*N/2 visits in a
single io_uring_enter(), with uring_lock held.
Patch 2 makes poll cancel all its matches in one pass, as futex and
waitid already do through io_cancel_remove(). Patch 1 is a prerequisite
and a fix on its own: __io_async_cancel() counts each io_try_cancel()
call as one, so CANCEL_ALL on futex or waitid requests reports 1 no
matter how many it cancelled. Patch 2 needs it to keep the poll count
right.
Reproducer, 80000 polls on one eventfd and a single CANCEL_FD|ALL:
#include <liburing.h>
#include <poll.h>
#include <sys/eventfd.h>
int main(void)
{
struct io_uring ring;
int fd = eventfd(0, 0), i;
io_uring_queue_init(4096, &ring, 0);
for (i = 0; i < 80000; i++) {
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
if (!sqe) {
io_uring_submit(&ring);
sqe = io_uring_get_sqe(&ring);
}
io_uring_prep_poll_add(sqe, fd, POLLIN);
}
io_uring_prep_cancel_fd(io_uring_get_sqe(&ring), fd,
IORING_ASYNC_CANCEL_ALL);
io_uring_submit(&ring);
return 0;
}
In a 4 vCPU KVM guest, "time ./repro" takes 17.06s of system time on
next-20261029 (lazy preemption) and 0.02s with these patches. On
v6.18.59 with voluntary preemption it takes 36.24s, and the soft lockup
watchdog fires during the cancel.
Testing, on next-20261029 and v6.18.59: liburing's cancel tests
(poll-cancel-all, poll-cancel, poll-cancel-ton, cancel-fd-userdata,
io-cancel, sync-cancel, cancel-race, futex, waitid), plus three new
tests that I'll send to liburing separately: a futex CANCEL_ALL count
(fails before patch 1), and poll CANCEL_ALL by user_data alone and with
1000 polls on one fd. All pass, except waitid's pidfd test on
v6.18.59, which fails with and without these patches. Not tested:
lockdep, KASAN, and SQPOLL or DEFER_TASKRUN rings for the new cases.
Shang En Sim (2):
io_uring/cancel: count all requests that a CANCEL_ALL cancels
io_uring/poll: cancel all matching requests in one pass
io_uring/cancel.c | 3 ++-
io_uring/poll.c | 39 +++++++++++++++++++++++++++++++++++++--
2 files changed, 39 insertions(+), 3 deletions(-)
base-commit: 70866cfa169d5ee149364267289e71d50f9a7ae9
--
2.56.0
next reply other threads:[~2026-10-30 5:04 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 5:03 Shang En Sim [this message]
2026-10-30 5:03 ` [PATCH 1/2] io_uring/cancel: count all requests that a CANCEL_ALL cancels Shang En Sim
2026-10-30 5:03 ` [PATCH 2/2] io_uring/poll: cancel all matching requests in one pass Shang En Sim
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=20261030050319.1448530-1-sim@shangen.org \
--to=sim@shangen.org \
--cc=axboe@kernel.dk \
--cc=io-uring@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®