diff options
| author | Jens Axboe <axboe@kernel.dk> | 2026-08-14 06:58:43 -0600 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2026-08-15 16:56:49 -0600 |
| commit | cd305ee3633a45fcf5f3a5d83f99f3cb77d87b6e (patch) | |
| tree | e1f283753d2fc2c70ee734f441137dca73f61308 /include | |
| parent | 3f3a6a16bbe8bde76532d9415438f8cdef439e5d (diff) | |
| download | linux-stable-cd305ee3633a45fcf5f3a5d83f99f3cb77d87b6e.tar.gz linux-stable-cd305ee3633a45fcf5f3a5d83f99f3cb77d87b6e.zip | |
io_uring: defer eventfd signaling when queued from a wakeup handler
io_req_local_work_add() signals the CQ ring eventfd inline when it is the
one to push the first entry onto ->work_list. For DEFER_TASKRUN rings that
add is frequently done from a waitqueue wakeup handler, where an
arbitrary waitqueue lock is held.
eventfd_signal_mask() only refuses to recurse when current->in_eventfd
is set, but that bit is set by eventfd_signal_mask() itself. If the wake
chain starts somewhere else, signal goes out inline and can feed back
into epoll.
Add IOU_F_TWQ_IN_WAKE, set it on the task_work add done from the three
waitqueue callbacks, and use it to force io_eventfd_signal() down the
existing call_rcu_hurry() deferral instead of signaling inline.
Fixes: 21a091b970cd ("io_uring: signal registered eventfd to process deferred task work")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20260813133843.2933127-1-4ncienth@gmail.com/
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/io_uring_types.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index a2c623a67a25..f6e90cc64a1f 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -20,6 +20,14 @@ enum { * It's also ignored unless IORING_SETUP_DEFER_TASKRUN is set. */ IOU_F_TWQ_LAZY_WAKE = 1, + + /* + * Set when task_work is queued from a waitqueue wakeup handler, where + * an arbitrary provider waitqueue lock is held. Signaling the CQ ring + * eventfd inline from there can recurse back into that lock through + * epoll, so the eventfd signal must be deferred. + */ + IOU_F_TWQ_IN_WAKE = 2, }; enum io_uring_cmd_flags { |
