Commit a730d204 authored by Pavel Begunkov's avatar Pavel Begunkov Committed by Jens Axboe
Browse files

io_uring/memmap: flag vmap'ed regions



Add internal flags for struct io_mapped_region. The first flag we need
is IO_REGION_F_VMAPPED, that indicates that the pointer has to be
unmapped on region destruction. For now all regions are vmap'ed, so it's
set unconditionally.

Signed-off-by: default avatarPavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/5a3d8046a038da97c0f8a8c8f1733fa3fc689d31.1732886067.git.asml.silence@gmail.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 7427b0b4
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -78,8 +78,9 @@ struct io_hash_table {

struct io_mapped_region {
	struct page		**pages;
	void			*vmap_ptr;
	size_t			nr_pages;
	void			*ptr;
	unsigned		nr_pages;
	unsigned		flags;
};

/*
+10 −4
Original line number Diff line number Diff line
@@ -202,14 +202,19 @@ void *__io_uaddr_map(struct page ***pages, unsigned short *npages,
	return ERR_PTR(-ENOMEM);
}

enum {
	/* memory was vmap'ed for the kernel, freeing the region vunmap's it */
	IO_REGION_F_VMAP			= 1,
};

void io_free_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr)
{
	if (mr->pages) {
		unpin_user_pages(mr->pages, mr->nr_pages);
		kvfree(mr->pages);
	}
	if (mr->vmap_ptr)
		vunmap(mr->vmap_ptr);
	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);

@@ -225,7 +230,7 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
	void *vptr;
	u64 end;

	if (WARN_ON_ONCE(mr->pages || mr->vmap_ptr || mr->nr_pages))
	if (WARN_ON_ONCE(mr->pages || mr->ptr || mr->nr_pages))
		return -EFAULT;
	if (memchr_inv(&reg->__resv, 0, sizeof(reg->__resv)))
		return -EINVAL;
@@ -260,8 +265,9 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,
	}

	mr->pages = pages;
	mr->vmap_ptr = vptr;
	mr->ptr = vptr;
	mr->nr_pages = nr_pages;
	mr->flags |= IO_REGION_F_VMAP;
	return 0;
out_free:
	if (pages_accounted)
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ int io_create_region(struct io_ring_ctx *ctx, struct io_mapped_region *mr,

static inline void *io_region_get_ptr(struct io_mapped_region *mr)
{
	return mr->vmap_ptr;
	return mr->ptr;
}

static inline bool io_region_is_set(struct io_mapped_region *mr)