On 4/22/26 12:25, Clément Léger wrote:
From: Pavel Begunkov <[email protected]>
...> 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 +541,7 @@ static struct io_zcrx_ifq *io_zcrx_ifq_alloc(struct
io_ring_ctx *ctx)
ifq->if_rxq = -1;
spin_lock_init(&ifq->rq.lock);
+ spin_lock_init(&ifq->ctx_lock);
mutex_init(&ifq->pp_lock);
refcount_set(&ifq->refs, 1);
refcount_set(&ifq->user_refs, 1);
@@ -585,6 +596,11 @@ static void io_zcrx_ifq_free(struct io_zcrx_ifq *ifq)
if (ifq->dev)
put_device(ifq->dev);
+ scoped_guard(spinlock_bh, &ifq->ctx_lock) {
+ if (ifq->master_ctx)
+ percpu_ref_put(&ifq->master_ctx->refs);
+ }
+
Something very odd happened here. It's not my patch but rather an edited
squash of two other patches. This particular hunk creates a circular
dependency, i.e. io_uring waits for this reference to be put down before
destroying the zcrx instance that triggers io_zcrx_ifq_free.
--
Pavel Begunkov