Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: stable@kernel.org
Fixes: 79cfe9e59c2a ("io_uring/register: add IORING_REGISTER_RESIZE_RINGS")
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

+26 -6
+26 -6
io_uring/register.c
··· 599 599 if (tail - old_head > p->sq_entries) 600 600 goto overflow; 601 601 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); 602 + unsigned index, dst_mask, src_mask; 603 + size_t sq_size; 604 604 605 - n.sq_sqes[dst_head] = o.sq_sqes[src_head]; 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); 606 616 } 607 617 WRITE_ONCE(n.rings->sq.head, old_head); 608 618 WRITE_ONCE(n.rings->sq.tail, tail); ··· 629 619 goto out; 630 620 } 631 621 for (i = old_head; i < tail; i++) { 632 - unsigned src_head = i & (ctx->cq_entries - 1); 633 - unsigned dst_head = i & (p->cq_entries - 1); 622 + unsigned index, dst_mask, src_mask; 623 + size_t cq_size; 634 624 635 - n.rings->cqes[dst_head] = o.rings->cqes[src_head]; 625 + index = i; 626 + cq_size = sizeof(struct io_uring_cqe); 627 + src_mask = ctx->cq_entries - 1; 628 + dst_mask = p->cq_entries - 1; 629 + if (ctx->flags & IORING_SETUP_CQE32) { 630 + index <<= 1; 631 + cq_size <<= 1; 632 + src_mask = (ctx->cq_entries << 1) - 1; 633 + dst_mask = (p->cq_entries << 1) - 1; 634 + } 635 + memcpy(&n.rings->cqes[index & dst_mask], &o.rings->cqes[index & src_mask], cq_size); 636 636 } 637 637 WRITE_ONCE(n.rings->cq.head, old_head); 638 638 WRITE_ONCE(n.rings->cq.tail, tail);