]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring: fix min_wait wakeups for SQPOLL
authorJens Axboe <axboe@kernel.dk>
Tue, 9 Dec 2025 20:25:23 +0000 (13:25 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 Jan 2026 11:57:06 +0000 (12:57 +0100)
commit e15cb2200b934e507273510ba6bc747d5cde24a3 upstream.

Using min_wait, two timeouts are given:

1) The min_wait timeout, within which up to 'wait_nr' events are
   waited for.
2) The overall long timeout, which is entered if no events are generated
   in the min_wait window.

If the min_wait has expired, any event being posted must wake the task.
For SQPOLL, that isn't the case, as it won't trigger the io_has_work()
condition, as it will have already processed the task_work that happened
when an event was posted. This causes any event to trigger post the
min_wait to not always cause the waiting application to wakeup, and
instead it will wait until the overall timeout has expired. This can be
shown in a test case that has a 1 second min_wait, with a 5 second
overall wait, even if an event triggers after 1.5 seconds:

axboe@m2max-kvm /d/iouring-mre (master)> zig-out/bin/iouring
info: MIN_TIMEOUT supported: true, features: 0x3ffff
info: Testing: min_wait=1000ms, timeout=5s, wait_nr=4
info: 1 cqes in 5000.2ms

where the expected result should be:

axboe@m2max-kvm /d/iouring-mre (master)> zig-out/bin/iouring
info: MIN_TIMEOUT supported: true, features: 0x3ffff
info: Testing: min_wait=1000ms, timeout=5s, wait_nr=4
info: 1 cqes in 1500.3ms

When the min_wait timeout triggers, reset the number of completions
needed to wake the task. This should ensure that any future events will
wake the task, regardless of how many events it originally wanted to
wait for.

Reported-by: Tip ten Brink <tip@tenbrinkmeijs.com>
Cc: stable@vger.kernel.org
Fixes: 1100c4a2656d ("io_uring: add support for batch wait timeout")
Link: https://github.com/axboe/liburing/issues/1477
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
io_uring/io_uring.c

index 765abec2571f03b45deef33c27750c8d0ca5a817..60adab71ad2d26b13155252500daee7e6fbf0fe7 100644 (file)
@@ -2551,6 +2551,9 @@ static enum hrtimer_restart io_cqring_min_timer_wakeup(struct hrtimer *timer)
                        goto out_wake;
        }
 
+       /* any generated CQE posted past this time should wake us up */
+       iowq->cq_tail = iowq->cq_min_tail;
+
        hrtimer_update_function(&iowq->t, io_cqring_timer_wakeup);
        hrtimer_set_expires(timer, iowq->timeout);
        return HRTIMER_RESTART;