diff options
| author | Pavel Begunkov <asml.silence@gmail.com> | 2025-10-16 14:23:23 +0100 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2025-10-20 10:37:56 -0600 |
| commit | 5b6d8a032e807c48a843fb81d9e3d74391f731ea (patch) | |
| tree | 19b56c57b2acef182ee31f5ab914661b8a0c6adc | |
| parent | dec10a1ad1d5f9d46e7f6e7c8b414a805e00717c (diff) | |
io_uring: only publish fully handled mem region
io_register_mem_region() can try to remove a region right after
publishing it. This non-atomicity is annoying. Do it in two steps
similar to io_register_mem_region(), create memory first and publish it
once the rest of the handling is done. Remove now unused
io_create_region_mmap_safe(), which was assumed to be a temporary
solution from day one.
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Reviewed-by: Gabriel Krisman Bertazi <krisman@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | io_uring/memmap.c | 21 | ||||
| -rw-r--r-- | io_uring/memmap.h | 12 | ||||
| -rw-r--r-- | io_uring/register.c | 11 |
3 files changed, 18 insertions, 26 deletions
diff --git a/io_uring/memmap.c b/io_uring/memmap.c index 2e99dffddfc5..aa388ecd4754 100644 --- a/io_uring/memmap.c +++ b/io_uring/memmap.c @@ -234,27 +234,6 @@ out_free: 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) { diff --git a/io_uring/memmap.h b/io_uring/memmap.h index 08419684e4bc..58002976e0c3 100644 --- a/io_uring/memmap.h +++ b/io_uring/memmap.h @@ -36,4 +36,16 @@ static inline bool io_region_is_set(struct io_mapped_region *mr) return !!mr->nr_pages; } +static inline void io_region_publish(struct io_ring_ctx *ctx, + struct io_mapped_region *src_region, + struct io_mapped_region *dst_region) +{ + /* + * Once published mmap can find it without holding only the ->mmap_lock + * and not ->uring_lock. + */ + guard(mutex)(&ctx->mmap_lock); + *dst_region = *src_region; +} + #endif diff --git a/io_uring/register.c b/io_uring/register.c index b11550ed940c..43eb02004824 100644 --- a/io_uring/register.c +++ b/io_uring/register.c @@ -576,6 +576,7 @@ static int io_register_mem_region(struct io_ring_ctx *ctx, void __user *uarg) struct io_uring_mem_region_reg reg; struct io_uring_region_desc __user *rd_uptr; struct io_uring_region_desc rd; + struct io_mapped_region region = {}; int ret; if (io_region_is_set(&ctx->param_region)) @@ -599,20 +600,20 @@ static int io_register_mem_region(struct io_ring_ctx *ctx, void __user *uarg) !(ctx->flags & IORING_SETUP_R_DISABLED)) return -EINVAL; - ret = io_create_region_mmap_safe(ctx, &ctx->param_region, &rd, - IORING_MAP_OFF_PARAM_REGION); + ret = io_create_region(ctx, ®ion, &rd, IORING_MAP_OFF_PARAM_REGION); if (ret) return ret; if (copy_to_user(rd_uptr, &rd, sizeof(rd))) { - guard(mutex)(&ctx->mmap_lock); - io_free_region(ctx, &ctx->param_region); + io_free_region(ctx, ®ion); return -EFAULT; } if (reg.flags & IORING_MEM_REGION_REG_WAIT_ARG) { - ctx->cq_wait_arg = io_region_get_ptr(&ctx->param_region); + ctx->cq_wait_arg = io_region_get_ptr(®ion); ctx->cq_wait_size = rd.size; } + + io_region_publish(ctx, ®ion, &ctx->param_region); return 0; } |