summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2022-03-05 15:47:26 -0700
committerJens Axboe <axboe@kernel.dk>2022-03-05 15:47:26 -0700
commit6231f56da7881bde6fb011e1b54d672f8fe5a224 (patch)
tree3360d7d6790c258f07676ec4cf27fc04106c1827
parent2de98320d5b02951936fc0ab677dd01e4fb2a7a7 (diff)
downloadliburing-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.c9
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;