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/zcrx: reverse ifq refcount

Add a refcount to struct io_zcrx_ifq to reverse the refcounting
relationship i.e. rings now reference ifqs instead. As a result of this,
remove ctx->refs that an ifq holds on a ring via the page pool memory
provider.

This ref ifq->refs is held by internal users of an ifq, namely rings and
the page pool memory provider associated with an ifq. This is needed to
keep the ifq around until the page pool is destroyed.

Since ifqs now no longer hold refs to ring ctx, there isn't a need to
split the cleanup of ifqs into two: io_shutdown_zcrx_ifqs() in
io_ring_exit_work() while waiting for ctx->refs to drop to 0, and
io_unregister_zcrx_ifqs() after. Remove io_shutdown_zcrx_ifqs().

Signed-off-by: David Wei <dw@davidwei.uk>
Co-developed-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Reviewed-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

David Wei and committed by
Jens Axboe
75c299a9 1bd95163

+15 -29
-5
io_uring/io_uring.c
··· 2988 2988 io_cqring_overflow_kill(ctx); 2989 2989 mutex_unlock(&ctx->uring_lock); 2990 2990 } 2991 - if (!xa_empty(&ctx->zcrx_ctxs)) { 2992 - mutex_lock(&ctx->uring_lock); 2993 - io_shutdown_zcrx_ifqs(ctx); 2994 - mutex_unlock(&ctx->uring_lock); 2995 - } 2996 2991 2997 2992 if (ctx->flags & IORING_SETUP_DEFER_TASKRUN) 2998 2993 io_move_task_work_from_local(ctx);
+14 -19
io_uring/zcrx.c
··· 479 479 return NULL; 480 480 481 481 ifq->if_rxq = -1; 482 - ifq->ctx = ctx; 483 482 spin_lock_init(&ifq->rq_lock); 484 483 mutex_init(&ifq->pp_lock); 484 + refcount_set(&ifq->refs, 1); 485 485 return ifq; 486 486 } 487 487 ··· 535 535 io_free_rbuf_ring(ifq); 536 536 mutex_destroy(&ifq->pp_lock); 537 537 kfree(ifq); 538 + } 539 + 540 + static void io_put_zcrx_ifq(struct io_zcrx_ifq *ifq) 541 + { 542 + if (refcount_dec_and_test(&ifq->refs)) 543 + io_zcrx_ifq_free(ifq); 538 544 } 539 545 540 546 struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ctx, ··· 598 592 ifq = io_zcrx_ifq_alloc(ctx); 599 593 if (!ifq) 600 594 return -ENOMEM; 595 + 601 596 if (ctx->user) { 602 597 get_uid(ctx->user); 603 598 ifq->user = ctx->user; ··· 721 714 } 722 715 } 723 716 724 - void io_shutdown_zcrx_ifqs(struct io_ring_ctx *ctx) 725 - { 726 - struct io_zcrx_ifq *ifq; 727 - unsigned long index; 728 - 729 - lockdep_assert_held(&ctx->uring_lock); 730 - 731 - xa_for_each(&ctx->zcrx_ctxs, index, ifq) { 732 - io_zcrx_scrub(ifq); 733 - io_close_queue(ifq); 734 - } 735 - } 736 - 737 717 void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx) 738 718 { 739 719 struct io_zcrx_ifq *ifq; ··· 737 743 } 738 744 if (!ifq) 739 745 break; 740 - io_zcrx_ifq_free(ifq); 746 + 747 + io_close_queue(ifq); 748 + io_zcrx_scrub(ifq); 749 + io_put_zcrx_ifq(ifq); 741 750 } 742 751 743 752 xa_destroy(&ctx->zcrx_ctxs); ··· 891 894 if (ret) 892 895 return ret; 893 896 894 - percpu_ref_get(&ifq->ctx->refs); 897 + refcount_inc(&ifq->refs); 895 898 return 0; 896 899 } 897 900 898 901 static void io_pp_zc_destroy(struct page_pool *pp) 899 902 { 900 - struct io_zcrx_ifq *ifq = io_pp_to_ifq(pp); 901 - 902 - percpu_ref_put(&ifq->ctx->refs); 903 + io_put_zcrx_ifq(io_pp_to_ifq(pp)); 903 904 } 904 905 905 906 static int io_pp_nl_fill(void *mp_priv, struct sk_buff *rsp,
+1 -5
io_uring/zcrx.h
··· 39 39 }; 40 40 41 41 struct io_zcrx_ifq { 42 - struct io_ring_ctx *ctx; 43 42 struct io_zcrx_area *area; 44 43 unsigned niov_shift; 45 44 struct user_struct *user; ··· 54 55 struct device *dev; 55 56 struct net_device *netdev; 56 57 netdevice_tracker netdev_tracker; 58 + refcount_t refs; 57 59 58 60 /* 59 61 * Page pool and net configuration lock, can be taken deeper in the ··· 70 70 int io_register_zcrx_ifq(struct io_ring_ctx *ctx, 71 71 struct io_uring_zcrx_ifq_reg __user *arg); 72 72 void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx); 73 - void io_shutdown_zcrx_ifqs(struct io_ring_ctx *ctx); 74 73 int io_zcrx_recv(struct io_kiocb *req, struct io_zcrx_ifq *ifq, 75 74 struct socket *sock, unsigned int flags, 76 75 unsigned issue_flags, unsigned int *len); ··· 82 83 return -EOPNOTSUPP; 83 84 } 84 85 static inline void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx) 85 - { 86 - } 87 - static inline void io_shutdown_zcrx_ifqs(struct io_ring_ctx *ctx) 88 86 { 89 87 } 90 88 static inline int io_zcrx_recv(struct io_kiocb *req, struct io_zcrx_ifq *ifq,