Re: [PATCH v2 1/6] io_uring/zcrx: add ctx pointer to zcrx
Vishwanath Seshagiri <[email protected]>
| Newsgroups | org.kernel.vger.io-uring,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.netdev |
|---|---|
| Message-ID | <CAJEWsO0hprYmXoGmkR1+yv+hM53dGVh5O=7M+xFAdqoQjKrA8w@mail.gmail.com> |
On Mon, May 18, 2026 at 8:36 AM Clément Léger <[email protected]> wrote: > > From: Pavel Begunkov <[email protected]> > > zcrx will need to have a pointer to an owning ctx to communicate > different events. Reference the ctx while it's attached to zcrx, and > rely on zcrx termination to drop the ctx to avoid circular ref deps. > > Co-developed-by: Vishwanath Seshagiri <[email protected]> > Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Vishwanath Seshagiri <[email protected]> > --- > io_uring/zcrx.c | 39 +++++++++++++++++++++++++++++++-------- > io_uring/zcrx.h | 3 +++ > 2 files changed, 34 insertions(+), 8 deletions(-) > > diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c > index 3f9632e7790a..34faf90423f4 100644 > --- a/io_uring/zcrx.c > +++ b/io_uring/zcrx.c > @@ -44,6 +44,17 @@ static inline struct io_zcrx_area *io_zcrx_iov_to_area(const struct net_iov *nio > return container_of(owner, struct io_zcrx_area, nia); > } > > +static bool zcrx_set_ring_ctx(struct io_zcrx_ifq *zcrx, > + struct io_ring_ctx *ctx) > +{ > + guard(spinlock_bh)(&zcrx->ctx_lock); > + if (zcrx->master_ctx) > + return false; > + percpu_ref_get(&ctx->refs); > + zcrx->master_ctx = ctx; > + return true; > +} > + > static inline struct page *io_zcrx_iov_page(const struct net_iov *niov) > { > struct io_zcrx_area *area = io_zcrx_iov_to_area(niov); > @@ -531,6 +542,7 @@ static struct io_zcrx_ifq *io_zcrx_ifq_alloc(struct io_ring_ctx *ctx) > return NULL; > > ifq->if_rxq = -1; > + spin_lock_init(&ifq->ctx_lock); > spin_lock_init(&ifq->rq.lock); > mutex_init(&ifq->pp_lock); > refcount_set(&ifq->refs, 1); > @@ -580,6 +592,8 @@ static void io_zcrx_ifq_free(struct io_zcrx_ifq *ifq) > return; > if (WARN_ON_ONCE(ifq->netdev != NULL)) > return; > + if (WARN_ON_ONCE(ifq->master_ctx)) > + return; > > if (ifq->area) > io_zcrx_free_area(ifq, ifq->area); > @@ -656,17 +670,24 @@ static void io_zcrx_scrub(struct io_zcrx_ifq *ifq) > } > } > > -static void zcrx_unregister_user(struct io_zcrx_ifq *ifq) > +static void zcrx_unregister_user(struct io_zcrx_ifq *ifq, struct io_ring_ctx *ctx) > { > + scoped_guard(spinlock_bh, &ifq->ctx_lock) { > + if (ctx && ifq->master_ctx == ctx) { > + ifq->master_ctx = NULL; > + percpu_ref_put(&ctx->refs); > + } > + } > + > if (refcount_dec_and_test(&ifq->user_refs)) { > io_close_queue(ifq); > io_zcrx_scrub(ifq); > } > } > > -static void zcrx_unregister(struct io_zcrx_ifq *ifq) > +static void zcrx_unregister(struct io_zcrx_ifq *ifq, struct io_ring_ctx *ctx) > { > - zcrx_unregister_user(ifq); > + zcrx_unregister_user(ifq, ctx); > io_put_zcrx_ifq(ifq); > } > > @@ -686,7 +707,7 @@ static int zcrx_box_release(struct inode *inode, struct file *file) > > if (WARN_ON_ONCE(!ifq)) > return -EFAULT; > - zcrx_unregister(ifq); > + zcrx_unregister(ifq, NULL); > return 0; > } > > @@ -711,7 +732,7 @@ static int zcrx_export(struct io_ring_ctx *ctx, struct io_zcrx_ifq *ifq, > file = anon_inode_create_getfile("[zcrx]", &zcrx_box_fops, > ifq, O_CLOEXEC, NULL); > if (IS_ERR(file)) { > - zcrx_unregister(ifq); > + zcrx_unregister(ifq, NULL); > return PTR_ERR(file); > } > > @@ -787,7 +808,7 @@ static int import_zcrx(struct io_ring_ctx *ctx, > scoped_guard(mutex, &ctx->mmap_lock) > xa_erase(&ctx->zcrx_ctxs, id); > err: > - zcrx_unregister(ifq); > + zcrx_unregister(ifq, ctx); > return ret; > } > > @@ -932,12 +953,14 @@ int io_register_zcrx(struct io_ring_ctx *ctx, > ret = -EFAULT; > goto err; > } > + > + zcrx_set_ring_ctx(ifq, ctx); > return 0; > err: > scoped_guard(mutex, &ctx->mmap_lock) > xa_erase(&ctx->zcrx_ctxs, id); > ifq_free: > - zcrx_unregister(ifq); > + zcrx_unregister(ifq, ctx); > return ret; > } > > @@ -967,7 +990,7 @@ void io_terminate_zcrx(struct io_ring_ctx *ctx) > break; > set_zcrx_entry_mark(ctx, id); > id++; > - zcrx_unregister_user(ifq); > + zcrx_unregister_user(ifq, ctx); > } > } > > diff --git a/io_uring/zcrx.h b/io_uring/zcrx.h > index 9e1a6a1b11e8..6b565d0bf6da 100644 > --- a/io_uring/zcrx.h > +++ b/io_uring/zcrx.h > @@ -73,6 +73,9 @@ struct io_zcrx_ifq { > */ > struct mutex pp_lock; > struct io_mapped_region rq_region; > + > + spinlock_t ctx_lock; > + struct io_ring_ctx *master_ctx; > }; > > #if defined(CONFIG_IO_URING_ZCRX) > -- > 2.53.0-Meta >