Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Pavel Begunkov and committed by
Jens Axboe
5b6d8a03 dec10a1a

+18 -26
-21
io_uring/memmap.c
··· 234 234 return ret; 235 235 } 236 236 237 - int io_create_region_mmap_safe(struct io_ring_ctx *ctx, struct io_mapped_region *mr, 238 - struct io_uring_region_desc *reg, 239 - unsigned long mmap_offset) 240 - { 241 - struct io_mapped_region tmp_mr; 242 - int ret; 243 - 244 - memcpy(&tmp_mr, mr, sizeof(tmp_mr)); 245 - ret = io_create_region(ctx, &tmp_mr, reg, mmap_offset); 246 - if (ret) 247 - return ret; 248 - 249 - /* 250 - * Once published mmap can find it without holding only the ->mmap_lock 251 - * and not ->uring_lock. 252 - */ 253 - guard(mutex)(&ctx->mmap_lock); 254 - memcpy(mr, &tmp_mr, sizeof(tmp_mr)); 255 - return 0; 256 - } 257 - 258 237 static struct io_mapped_region *io_mmap_get_region(struct io_ring_ctx *ctx, 259 238 loff_t pgoff) 260 239 {
+12
io_uring/memmap.h
··· 36 36 return !!mr->nr_pages; 37 37 } 38 38 39 + static inline void io_region_publish(struct io_ring_ctx *ctx, 40 + struct io_mapped_region *src_region, 41 + struct io_mapped_region *dst_region) 42 + { 43 + /* 44 + * Once published mmap can find it without holding only the ->mmap_lock 45 + * and not ->uring_lock. 46 + */ 47 + guard(mutex)(&ctx->mmap_lock); 48 + *dst_region = *src_region; 49 + } 50 + 39 51 #endif
+6 -5
io_uring/register.c
··· 576 576 struct io_uring_mem_region_reg reg; 577 577 struct io_uring_region_desc __user *rd_uptr; 578 578 struct io_uring_region_desc rd; 579 + struct io_mapped_region region = {}; 579 580 int ret; 580 581 581 582 if (io_region_is_set(&ctx->param_region)) ··· 600 599 !(ctx->flags & IORING_SETUP_R_DISABLED)) 601 600 return -EINVAL; 602 601 603 - ret = io_create_region_mmap_safe(ctx, &ctx->param_region, &rd, 604 - IORING_MAP_OFF_PARAM_REGION); 602 + ret = io_create_region(ctx, &region, &rd, IORING_MAP_OFF_PARAM_REGION); 605 603 if (ret) 606 604 return ret; 607 605 if (copy_to_user(rd_uptr, &rd, sizeof(rd))) { 608 - guard(mutex)(&ctx->mmap_lock); 609 - io_free_region(ctx, &ctx->param_region); 606 + io_free_region(ctx, &region); 610 607 return -EFAULT; 611 608 } 612 609 613 610 if (reg.flags & IORING_MEM_REGION_REG_WAIT_ARG) { 614 - ctx->cq_wait_arg = io_region_get_ptr(&ctx->param_region); 611 + ctx->cq_wait_arg = io_region_get_ptr(&region); 615 612 ctx->cq_wait_size = rd.size; 616 613 } 614 + 615 + io_region_publish(ctx, &region, &ctx->param_region); 617 616 return 0; 618 617 } 619 618