Skip to content

Commit 45cd957

Browse files
committed
io_uring/register: fix ring resizing with mixed/large SQEs/CQEs
The ring resizing only properly handles "normal" sized SQEs or CQEs, if there are pending entries around a resize. This normally should not be the case, but the code is supposed to handle this regardless. For the mixed SQE/CQE cases, the current copying works fine as they are indexed in the same way. Each half is just copied separately. But for fixed large SQEs and CQEs, the iteration and copy need to take that into account. Cc: [email protected] Fixes: 79cfe9e ("io_uring/register: add IORING_REGISTER_RESIZE_RINGS") Reviewed-by: Gabriel Krisman Bertazi <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 7faaa68 commit 45cd957

1 file changed

Lines changed: 28 additions & 8 deletions

File tree

io_uring/register.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,20 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
599599
if (tail - old_head > p->sq_entries)
600600
goto overflow;
601601
for (i = old_head; i < tail; i++) {
602-
unsigned src_head = i & (ctx->sq_entries - 1);
603-
unsigned dst_head = i & (p->sq_entries - 1);
604-
605-
n.sq_sqes[dst_head] = o.sq_sqes[src_head];
602+
unsigned index, dst_mask, src_mask;
603+
size_t sq_size;
604+
605+
index = i;
606+
sq_size = sizeof(struct io_uring_sqe);
607+
src_mask = ctx->sq_entries - 1;
608+
dst_mask = p->sq_entries - 1;
609+
if (ctx->flags & IORING_SETUP_SQE128) {
610+
index <<= 1;
611+
sq_size <<= 1;
612+
src_mask = (ctx->sq_entries << 1) - 1;
613+
dst_mask = (p->sq_entries << 1) - 1;
614+
}
615+
memcpy(&n.sq_sqes[index & dst_mask], &o.sq_sqes[index & src_mask], sq_size);
606616
}
607617
WRITE_ONCE(n.rings->sq.head, old_head);
608618
WRITE_ONCE(n.rings->sq.tail, tail);
@@ -619,10 +629,20 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
619629
goto out;
620630
}
621631
for (i = old_head; i < tail; i++) {
622-
unsigned src_head = i & (ctx->cq_entries - 1);
623-
unsigned dst_head = i & (p->cq_entries - 1);
624-
625-
n.rings->cqes[dst_head] = o.rings->cqes[src_head];
632+
unsigned index, dst_mask, src_mask;
633+
size_t cq_size;
634+
635+
index = i;
636+
cq_size = sizeof(struct io_uring_cqe);
637+
src_mask = ctx->cq_entries - 1;
638+
dst_mask = p->cq_entries - 1;
639+
if (ctx->flags & IORING_SETUP_CQE32) {
640+
index <<= 1;
641+
cq_size <<= 1;
642+
src_mask = (ctx->cq_entries << 1) - 1;
643+
dst_mask = (p->cq_entries << 1) - 1;
644+
}
645+
memcpy(&n.rings->cqes[index & dst_mask], &o.rings->cqes[index & src_mask], cq_size);
626646
}
627647
WRITE_ONCE(n.rings->cq.head, old_head);
628648
WRITE_ONCE(n.rings->cq.tail, tail);

0 commit comments

Comments
 (0)