From f5f2de273c6c5a21dad75f5a83158886726b5d9f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 25 Jul 2025 05:05:36 -0600 Subject: [PATCH] io_uring/chan: grab reference to destination ring Grab a reference to the destination ring, and store it in the io_queue_chan struct. When either end of the channel gets closed, eg when either of the rings go away, then the reference is dropped unconditionally. Hence the stored ctx must only be used within a RCU read lock region. Note that channels only support DEFER_TASKRUN targets, and such rings will call synchronize_rcu() before the ring (and task) can go away. This makes it safe to use ->dst_ring inside rcu_read_lock(), even though the reference to the ring is put during unregistration. Signed-off-by: Jens Axboe --- io_uring/chan.c | 8 ++++++++ io_uring/chan.h | 1 + 2 files changed, 9 insertions(+) diff --git a/io_uring/chan.c b/io_uring/chan.c index b4f16aec2ffa..e205bfd1f286 100644 --- a/io_uring/chan.c +++ b/io_uring/chan.c @@ -33,14 +33,20 @@ void io_unregister_queue_chans(struct io_ring_ctx *ctx) lockdep_assert_held(&ctx->uring_lock); + rcu_read_lock(); xa_for_each(&ctx->xa_src_chan, index, c) { if (atomic_dec_and_test(&c->refs)) kfree_rcu(c, rcu_head); } xa_for_each(&ctx->xa_dst_chan, index, c) { + if (rcu_dereference(c->dst_ring) == ctx) { + percpu_ref_put(&ctx->refs); + rcu_assign_pointer(c->dst_ring, NULL); + } if (atomic_dec_and_test(&c->refs)) kfree_rcu(c, rcu_head); } + rcu_read_unlock(); xa_destroy(&ctx->xa_src_chan); xa_destroy(&ctx->xa_dst_chan); } @@ -93,6 +99,8 @@ static struct io_queue_chan *__io_register_queue_chan(struct io_ring_ctx *ctx, return ERR_PTR(ret); } + percpu_ref_get(&dst->refs); + rcu_assign_pointer(c->dst_ring, dst); return c; } diff --git a/io_uring/chan.h b/io_uring/chan.h index cea16b5d2f4e..a8dc962fc61f 100644 --- a/io_uring/chan.h +++ b/io_uring/chan.h @@ -12,6 +12,7 @@ struct io_queue_chan { __u32 mask; __u32 tail; __u32 resp_id; + struct io_ring_ctx __rcu *dst_ring; struct rcu_head rcu_head; struct io_queue_chan_entry data[]; }; -- 2.25.1