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);
}
return ERR_PTR(ret);
}
+ percpu_ref_get(&dst->refs);
+ rcu_assign_pointer(c->dst_ring, dst);
return c;
}
__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[];
};