diff options
author | Jens Axboe <axboe@kernel.dk> | 2022-03-05 15:47:26 -0700 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2022-03-05 15:47:26 -0700 |
commit | 6231f56da7881bde6fb011e1b54d672f8fe5a224 (patch) | |
tree | 3360d7d6790c258f07676ec4cf27fc04106c1827 | |
parent | 2de98320d5b02951936fc0ab677dd01e4fb2a7a7 (diff) | |
download | liburing-6231f56da7881bde6fb011e1b54d672f8fe5a224.tar.gz liburing-6231f56da7881bde6fb011e1b54d672f8fe5a224.tar.bz2 |
src/queue: don't keep looping for IOPOLL peek operation
A previous commit broke peek with an IOPOLL ring, making it loop
continually even if we have wait_for == 0 and submit == 0.
It's only necessary to enter the kernel for that condition once, don't
keep looping trying to poll for zero events.
Fixes: 333561791386 ("Fix __io_uring_get_cqe() for IORING_SETUP_IOPOLL")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | src/queue.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/queue.c b/src/queue.c index f9b6c86..ef09eb5 100644 --- a/src/queue.c +++ b/src/queue.c @@ -85,6 +85,7 @@ static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_pt struct get_data *data) { struct io_uring_cqe *cqe = NULL; + bool looped = false; int err; do { @@ -97,7 +98,12 @@ static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_pt if (err) break; if (!cqe && !data->wait_nr && !data->submit) { - if (!cq_ring_needs_enter(ring)) { + /* + * If we already looped once, we already entererd + * the kernel. Since there's nothing to submit or + * wait for, don't keep retrying. + */ + if (looped || !cq_ring_needs_enter(ring)) { err = -EAGAIN; break; } @@ -123,6 +129,7 @@ static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_pt data->submit -= ret; if (cqe) break; + looped = true; } while (1); *cqe_ptr = cqe; |