io_wake_function() returns -1 if the waiter it is called for doesn't have enough events yet, which makes __wake_up_common() stop walking the wait queue. That assumes that the waiters behind it can't be satisfied either. Each waiter has its own target though, computed from the min_complete it passed in: thread A: io_uring_enter(GETEVENTS, min_complete = 10) // queued first thread B: io_uring_enter(GETEVENTS, min_complete = 1) one CQE is posted: A isn't woken, and B isn't even considered B keeps sleeping with the event it asked for sitting in the CQ ring, until A's demand is met or a timeout or signal ends the wait. Return 0 to carry on with the next waiter. Only waiters whose condition is met are woken, like before. Fixes: bda521624e75 ("io_uring: make CQ ring wakeups be more efficient") Assisted-by: LLM Signed-off-by: Josef Bacik --- io_uring/wait.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/io_uring/wait.c b/io_uring/wait.c index 5093365e9eb2..38425d4cb7bc 100644 --- a/io_uring/wait.c +++ b/io_uring/wait.c @@ -26,7 +26,8 @@ static int io_wake_function(struct wait_queue_entry *curr, unsigned int mode, */ if (io_should_wake(iowq) || io_has_work(iowq->ctx)) return autoremove_wake_function(curr, mode, wake_flags, key); - return -1; + /* keep going, a waiter further down may be content with less */ + return 0; } int io_run_task_work_sig(struct io_ring_ctx *ctx) -- 2.55.0