Commit 74f464e9 authored by Jens Axboe's avatar Jens Axboe

io_uring: fix CQ overflow condition

This is a leftover from when the rings initially were not free flowing,
and hence a test for tail + 1 == head would indicate full. Since we now
let them wrap instead of mask them with the size, we need to check if
they drift more than the ring size from each other.

This fixes a case where we'd overwrite CQ ring entries, if the user
failed to reap completions. Both cases would ultimately result in lost
completions as the application violated the depth it asked for. The only
difference is that before this fix we'd return invalid entries for the
overflowed completions, instead of properly flagging it in the
cq_ring->overflow variable.
Reported-by: default avatarStefan Bühler <source@stbuehler.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent b19062a5
...@@ -338,7 +338,7 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx) ...@@ -338,7 +338,7 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx)
tail = ctx->cached_cq_tail; tail = ctx->cached_cq_tail;
/* See comment at the top of the file */ /* See comment at the top of the file */
smp_rmb(); smp_rmb();
if (tail + 1 == READ_ONCE(ring->r.head)) if (tail - READ_ONCE(ring->r.head) == ring->ring_entries)
return NULL; return NULL;
ctx->cached_cq_tail++; ctx->cached_cq_tail++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment