summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2026-08-14 06:58:43 -0600
committerJens Axboe <axboe@kernel.dk>2026-08-15 16:56:49 -0600
commitcd305ee3633a45fcf5f3a5d83f99f3cb77d87b6e (patch)
treee1f283753d2fc2c70ee734f441137dca73f61308 /include
parent3f3a6a16bbe8bde76532d9415438f8cdef439e5d (diff)
downloadlinux-cd305ee3633a45fcf5f3a5d83f99f3cb77d87b6e.tar.gz
linux-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.h8
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 {