diff options
author | Pavel Begunkov <asml.silence@gmail.com> | 2024-11-29 13:34:29 +0000 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2024-12-23 08:17:16 -0700 |
commit | a90558b36cceeb546c19b3cd17ed94f9810f8eec (patch) | |
tree | 2c4280681f6c6b628815cf3f18b1241bca0bc3e3 /io_uring/memmap.c | |
parent | c4d0ac1c1567ee822529124a3dc10b384838c3bc (diff) |
io_uring/memmap: helper for pinning region pages
In preparation to adding kernel allocated regions extract a new helper
that pins user pages.
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/a17d7c39c3de4266b66b75b2dcf768150e1fc618.1732886067.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring/memmap.c')
-rw-r--r-- | io_uring/memmap.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/io_uring/memmap.c b/io_uring/memmap.c index fd348c98f64f..5d261e07c2e3 100644 --- a/io_uring/memmap.c +++ b/io_uring/memmap.c @@ -246,10 +246,28 @@ static int io_region_init_ptr(struct io_mapped_region *mr) return 0; } +static int io_region_pin_pages(struct io_ring_ctx *ctx, + struct io_mapped_region *mr, + struct io_uring_region_desc *reg) +{ + unsigned long size = mr->nr_pages << PAGE_SHIFT; + struct page **pages; + int nr_pages; + + pages = io_pin_pages(reg->user_addr, size, &nr_pages); + if (IS_ERR(pages)) + return PTR_ERR(pages); + if (WARN_ON_ONCE(nr_pages != mr->nr_pages)) + return -EFAULT; + + mr->pages = pages; + mr->flags |= IO_REGION_F_USER_PROVIDED; + return 0; +} + int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr, struct io_uring_region_desc *reg) { - struct page **pages; int nr_pages, ret; u64 end; @@ -278,13 +296,9 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr, } mr->nr_pages = nr_pages; - pages = io_pin_pages(reg->user_addr, reg->size, &nr_pages); - if (IS_ERR(pages)) { - ret = PTR_ERR(pages); + ret = io_region_pin_pages(ctx, mr, reg); + if (ret) goto out_free; - } - mr->pages = pages; - mr->flags |= IO_REGION_F_USER_PROVIDED; ret = io_region_init_ptr(mr); if (ret) |