Skip to content

Commit 8078486

Browse files
isilenceaxboe
authored andcommitted
io_uring: use region api for SQ
Convert internal parts of the SQ managment to the region API. Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/1fb73ced6b835cb319ab0fe1dc0b2e982a9a5650.1732886067.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 02255d5 commit 8078486

File tree

4 files changed

+32
-45
lines changed

4 files changed

+32
-45
lines changed

include/linux/io_uring_types.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,9 @@ struct io_ring_ctx {
432432
* the gup'ed pages for the two rings, and the sqes.
433433
*/
434434
unsigned short n_ring_pages;
435-
unsigned short n_sqe_pages;
436435
struct page **ring_pages;
437-
struct page **sqe_pages;
438436

437+
struct io_mapped_region sq_region;
439438
/* used for optimised request parameter and wait argument passing */
440439
struct io_mapped_region param_region;
441440
};

io_uring/io_uring.c

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,29 +2641,19 @@ static void *io_rings_map(struct io_ring_ctx *ctx, unsigned long uaddr,
26412641
size);
26422642
}
26432643

2644-
static void *io_sqes_map(struct io_ring_ctx *ctx, unsigned long uaddr,
2645-
size_t size)
2646-
{
2647-
return __io_uaddr_map(&ctx->sqe_pages, &ctx->n_sqe_pages, uaddr,
2648-
size);
2649-
}
2650-
26512644
static void io_rings_free(struct io_ring_ctx *ctx)
26522645
{
26532646
if (!(ctx->flags & IORING_SETUP_NO_MMAP)) {
26542647
io_pages_unmap(ctx->rings, &ctx->ring_pages, &ctx->n_ring_pages,
26552648
true);
2656-
io_pages_unmap(ctx->sq_sqes, &ctx->sqe_pages, &ctx->n_sqe_pages,
2657-
true);
26582649
} else {
26592650
io_pages_free(&ctx->ring_pages, ctx->n_ring_pages);
26602651
ctx->n_ring_pages = 0;
2661-
io_pages_free(&ctx->sqe_pages, ctx->n_sqe_pages);
2662-
ctx->n_sqe_pages = 0;
26632652
vunmap(ctx->rings);
2664-
vunmap(ctx->sq_sqes);
26652653
}
26662654

2655+
io_free_region(ctx, &ctx->sq_region);
2656+
26672657
ctx->rings = NULL;
26682658
ctx->sq_sqes = NULL;
26692659
}
@@ -3481,9 +3471,10 @@ bool io_is_uring_fops(struct file *file)
34813471
static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx,
34823472
struct io_uring_params *p)
34833473
{
3474+
struct io_uring_region_desc rd;
34843475
struct io_rings *rings;
34853476
size_t size, sq_array_offset;
3486-
void *ptr;
3477+
int ret;
34873478

34883479
/* make sure these are sane, as we already accounted them */
34893480
ctx->sq_entries = p->sq_entries;
@@ -3519,17 +3510,18 @@ static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx,
35193510
return -EOVERFLOW;
35203511
}
35213512

3522-
if (!(ctx->flags & IORING_SETUP_NO_MMAP))
3523-
ptr = io_pages_map(&ctx->sqe_pages, &ctx->n_sqe_pages, size);
3524-
else
3525-
ptr = io_sqes_map(ctx, p->sq_off.user_addr, size);
3526-
3527-
if (IS_ERR(ptr)) {
3513+
memset(&rd, 0, sizeof(rd));
3514+
rd.size = PAGE_ALIGN(size);
3515+
if (ctx->flags & IORING_SETUP_NO_MMAP) {
3516+
rd.user_addr = p->sq_off.user_addr;
3517+
rd.flags |= IORING_MEM_REGION_TYPE_USER;
3518+
}
3519+
ret = io_create_region(ctx, &ctx->sq_region, &rd, IORING_OFF_SQES);
3520+
if (ret) {
35283521
io_rings_free(ctx);
3529-
return PTR_ERR(ptr);
3522+
return ret;
35303523
}
3531-
3532-
ctx->sq_sqes = ptr;
3524+
ctx->sq_sqes = io_region_get_ptr(&ctx->sq_region);
35333525
return 0;
35343526
}
35353527

io_uring/memmap.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,7 @@ __cold int io_uring_mmap(struct file *file, struct vm_area_struct *vma)
474474
npages = min(ctx->n_ring_pages, (sz + PAGE_SIZE - 1) >> PAGE_SHIFT);
475475
return io_uring_mmap_pages(ctx, vma, ctx->ring_pages, npages);
476476
case IORING_OFF_SQES:
477-
return io_uring_mmap_pages(ctx, vma, ctx->sqe_pages,
478-
ctx->n_sqe_pages);
477+
return io_region_mmap(ctx, &ctx->sq_region, vma);
479478
case IORING_OFF_PBUF_RING:
480479
return io_pbuf_mmap(file, vma);
481480
case IORING_MAP_OFF_PARAM_REGION:

io_uring/register.c

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,11 @@ static int io_register_clock(struct io_ring_ctx *ctx,
368368
*/
369369
struct io_ring_ctx_rings {
370370
unsigned short n_ring_pages;
371-
unsigned short n_sqe_pages;
372371
struct page **ring_pages;
373-
struct page **sqe_pages;
374-
struct io_uring_sqe *sq_sqes;
375372
struct io_rings *rings;
373+
374+
struct io_uring_sqe *sq_sqes;
375+
struct io_mapped_region sq_region;
376376
};
377377

378378
static void io_register_free_rings(struct io_ring_ctx *ctx,
@@ -382,14 +382,11 @@ static void io_register_free_rings(struct io_ring_ctx *ctx,
382382
if (!(p->flags & IORING_SETUP_NO_MMAP)) {
383383
io_pages_unmap(r->rings, &r->ring_pages, &r->n_ring_pages,
384384
true);
385-
io_pages_unmap(r->sq_sqes, &r->sqe_pages, &r->n_sqe_pages,
386-
true);
387385
} else {
388386
io_pages_free(&r->ring_pages, r->n_ring_pages);
389-
io_pages_free(&r->sqe_pages, r->n_sqe_pages);
390387
vunmap(r->rings);
391-
vunmap(r->sq_sqes);
392388
}
389+
io_free_region(ctx, &r->sq_region);
393390
}
394391

395392
#define swap_old(ctx, o, n, field) \
@@ -404,11 +401,11 @@ static void io_register_free_rings(struct io_ring_ctx *ctx,
404401

405402
static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
406403
{
404+
struct io_uring_region_desc rd;
407405
struct io_ring_ctx_rings o = { }, n = { }, *to_free = NULL;
408406
size_t size, sq_array_offset;
409407
struct io_uring_params p;
410408
unsigned i, tail;
411-
void *ptr;
412409
int ret;
413410

414411
/* for single issuer, must be owner resizing */
@@ -469,16 +466,18 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
469466
return -EOVERFLOW;
470467
}
471468

472-
if (!(p.flags & IORING_SETUP_NO_MMAP))
473-
ptr = io_pages_map(&n.sqe_pages, &n.n_sqe_pages, size);
474-
else
475-
ptr = __io_uaddr_map(&n.sqe_pages, &n.n_sqe_pages,
476-
p.sq_off.user_addr,
477-
size);
478-
if (IS_ERR(ptr)) {
469+
memset(&rd, 0, sizeof(rd));
470+
rd.size = PAGE_ALIGN(size);
471+
if (p.flags & IORING_SETUP_NO_MMAP) {
472+
rd.user_addr = p.sq_off.user_addr;
473+
rd.flags |= IORING_MEM_REGION_TYPE_USER;
474+
}
475+
ret = io_create_region_mmap_safe(ctx, &n.sq_region, &rd, IORING_OFF_SQES);
476+
if (ret) {
479477
io_register_free_rings(ctx, &p, &n);
480-
return PTR_ERR(ptr);
478+
return ret;
481479
}
480+
n.sq_sqes = io_region_get_ptr(&n.sq_region);
482481

483482
/*
484483
* If using SQPOLL, park the thread
@@ -509,7 +508,6 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
509508
* Now copy SQ and CQ entries, if any. If either of the destination
510509
* rings can't hold what is already there, then fail the operation.
511510
*/
512-
n.sq_sqes = ptr;
513511
tail = o.rings->sq.tail;
514512
if (tail - o.rings->sq.head > p.sq_entries)
515513
goto overflow;
@@ -558,9 +556,8 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg)
558556
ctx->rings = n.rings;
559557
ctx->sq_sqes = n.sq_sqes;
560558
swap_old(ctx, o, n, n_ring_pages);
561-
swap_old(ctx, o, n, n_sqe_pages);
562559
swap_old(ctx, o, n, ring_pages);
563-
swap_old(ctx, o, n, sqe_pages);
560+
swap_old(ctx, o, n, sq_region);
564561
to_free = &o;
565562
ret = 0;
566563
out:

0 commit comments

Comments
 (0)