summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYufan Chen <ericterminal@gmail.com>2026-05-03 20:57:10 +0300
committerJens Axboe <axboe@kernel.dk>2026-05-04 08:21:40 +0300
commit04fe9aeb4f3c0999e6715385664c677469dfd8f4 (patch)
treeb9e827e2087baab671144fc008b48119028d3a78
parentb8c2e9e27636b92dc96c12f16894cbc60c58a306 (diff)
downloadlinux-04fe9aeb4f3c0999e6715385664c677469dfd8f4.tar.xz
io_uring/eventfd: reset deferred signal state
Recursive eventfd wakeups must defer io_uring eventfd signaling because eventfd_signal_mask() rejects reentry from eventfd wakeup handlers. The io_ev_fd ops bit tracks an outstanding deferred signal so that the same rcu_head is not queued twice. That bit is only set today. Once the first deferred callback runs, later recursive notifications still see the bit set and skip queueing another deferred signal. This can leave new completions without a matching eventfd wake after the first recursive deferral. Clear the pending bit before issuing the deferred signal. If the wakeup path recurses while the callback runs, a new signal can be queued for the next RCU grace period while the current callback keeps its reference until it returns. Signed-off-by: Yufan Chen <ericterminal@gmail.com> Fixes: 60b6c075e8eb ("io_uring/eventfd: move to more idiomatic RCU free usage") Link: https://patch.msgid.link/20260503175710.37209-1-yufan.chen@linux.dev Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--io_uring/eventfd.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/io_uring/eventfd.c b/io_uring/eventfd.c
index 3da028500f76..d656cc2a0b9b 100644
--- a/io_uring/eventfd.c
+++ b/io_uring/eventfd.c
@@ -43,6 +43,7 @@ static void io_eventfd_do_signal(struct rcu_head *rcu)
{
struct io_ev_fd *ev_fd = container_of(rcu, struct io_ev_fd, rcu);
+ atomic_andnot(BIT(IO_EVENTFD_OP_SIGNAL_BIT), &ev_fd->ops);
eventfd_signal_mask(ev_fd->cq_ev_fd, EPOLL_URING_WAKE);
io_eventfd_put(ev_fd);
}