io_uring: fix free entry check for 32b CQEs on CQE32 rings

On CQE32 rings, len is in units of 32b CQEs when io_cqe_cache_refill()
checks for free entries, so requiring cqe32 + 1 of them means insisting
on 2 free CQEs where 1 is enough, and a ring with a single free entry
needlessly goes to overflow.

Check for a free CQE directly in that case, and keep the cqe32 + 1 check
for CQE_MIXED where the units are 16b.

Fixes: e26dca67fd ("io_uring: add support for IORING_SETUP_CQE_MIXED")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Link: https://patch.msgid.link/20260919203516.2581409-1-benquike@gmail.com
[axboe: split from Hui's original patch, edited commit message]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Hui Peng 2026-09-19 20:35:18 +00:00 committed by Jens Axboe
parent 2107751744
commit ab5853c068

View File

@ -743,12 +743,13 @@ bool io_cqe_cache_refill(struct io_ring_ctx *ctx, bool overflow, bool cqe32)
free = ctx->cq_entries - io_cqring_queued(ctx);
/* we need a contiguous range, limit based on the current array offset */
len = min(free, ctx->cq_entries - off);
if (len < (cqe32 + 1))
return false;
if (ctx->flags & IORING_SETUP_CQE32) {
if (!len)
return false;
off <<= 1;
len <<= 1;
} else if (len < (cqe32 + 1)) {
return false;
}
ctx->cqe_cached = &rings->cqes[off];