summaryrefslogtreecommitdiff
path: root/io_uring/memmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'io_uring/memmap.c')
-rw-r--r--io_uring/memmap.c59
1 files changed, 17 insertions, 42 deletions
diff --git a/io_uring/memmap.c b/io_uring/memmap.c
index 2e99dffddfc5..dc4bfc5b6fb8 100644
--- a/io_uring/memmap.c
+++ b/io_uring/memmap.c
@@ -15,26 +15,26 @@
#include "rsrc.h"
#include "zcrx.h"
-static void *io_mem_alloc_compound(struct page **pages, int nr_pages,
- size_t size, gfp_t gfp)
+static bool io_mem_alloc_compound(struct page **pages, int nr_pages,
+ size_t size, gfp_t gfp)
{
struct page *page;
int i, order;
order = get_order(size);
if (order > MAX_PAGE_ORDER)
- return ERR_PTR(-ENOMEM);
+ return false;
else if (order)
gfp |= __GFP_COMP;
page = alloc_pages(gfp, order);
if (!page)
- return ERR_PTR(-ENOMEM);
+ return false;
for (i = 0; i < nr_pages; i++)
pages[i] = page + i;
- return page_address(page);
+ return true;
}
struct page **io_pin_pages(unsigned long uaddr, unsigned long len, int *npages)
@@ -88,7 +88,7 @@ enum {
IO_REGION_F_SINGLE_REF = 4,
};
-void io_free_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr)
+void io_free_region(struct user_struct *user, struct io_mapped_region *mr)
{
if (mr->pages) {
long nr_refs = mr->nr_pages;
@@ -105,8 +105,8 @@ void io_free_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr)
}
if ((mr->flags & IO_REGION_F_VMAP) && mr->ptr)
vunmap(mr->ptr);
- if (mr->nr_pages && ctx->user)
- __io_unaccount_mem(ctx->user, mr->nr_pages);
+ if (mr->nr_pages && user)
+ __io_unaccount_mem(user, mr->nr_pages);
memset(mr, 0, sizeof(*mr));
}
@@ -131,11 +131,10 @@ 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)
+static int io_region_pin_pages(struct io_mapped_region *mr,
+ struct io_uring_region_desc *reg)
{
- unsigned long size = mr->nr_pages << PAGE_SHIFT;
+ size_t size = io_region_size(mr);
struct page **pages;
int nr_pages;
@@ -150,23 +149,20 @@ static int io_region_pin_pages(struct io_ring_ctx *ctx,
return 0;
}
-static int io_region_allocate_pages(struct io_ring_ctx *ctx,
- struct io_mapped_region *mr,
+static int io_region_allocate_pages(struct io_mapped_region *mr,
struct io_uring_region_desc *reg,
unsigned long mmap_offset)
{
gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_NOWARN;
- size_t size = (size_t) mr->nr_pages << PAGE_SHIFT;
+ size_t size = io_region_size(mr);
unsigned long nr_allocated;
struct page **pages;
- void *p;
pages = kvmalloc_array(mr->nr_pages, sizeof(*pages), gfp);
if (!pages)
return -ENOMEM;
- p = io_mem_alloc_compound(pages, mr->nr_pages, size, gfp);
- if (!IS_ERR(p)) {
+ if (io_mem_alloc_compound(pages, mr->nr_pages, size, gfp)) {
mr->flags |= IO_REGION_F_SINGLE_REF;
goto done;
}
@@ -219,9 +215,9 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
mr->nr_pages = nr_pages;
if (reg->flags & IORING_MEM_REGION_TYPE_USER)
- ret = io_region_pin_pages(ctx, mr, reg);
+ ret = io_region_pin_pages(mr, reg);
else
- ret = io_region_allocate_pages(ctx, mr, reg, mmap_offset);
+ ret = io_region_allocate_pages(mr, reg, mmap_offset);
if (ret)
goto out_free;
@@ -230,31 +226,10 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
goto out_free;
return 0;
out_free:
- io_free_region(ctx, mr);
+ io_free_region(ctx->user, mr);
return ret;
}
-int io_create_region_mmap_safe(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
- struct io_uring_region_desc *reg,
- unsigned long mmap_offset)
-{
- struct io_mapped_region tmp_mr;
- int ret;
-
- memcpy(&tmp_mr, mr, sizeof(tmp_mr));
- ret = io_create_region(ctx, &tmp_mr, reg, mmap_offset);
- if (ret)
- return ret;
-
- /*
- * Once published mmap can find it without holding only the ->mmap_lock
- * and not ->uring_lock.
- */
- guard(mutex)(&ctx->mmap_lock);
- memcpy(mr, &tmp_mr, sizeof(tmp_mr));
- return 0;
-}
-
static struct io_mapped_region *io_mmap_get_region(struct io_ring_ctx *ctx,
loff_t pgoff)
{