io_cqring_overflow_kill(ctx);
mutex_unlock(&ctx->uring_lock);
}
- if (!xa_empty(&ctx->zcrx_ctxs)) {
- mutex_lock(&ctx->uring_lock);
- io_shutdown_zcrx_ifqs(ctx);
- mutex_unlock(&ctx->uring_lock);
- }
if (ctx->flags & IORING_SETUP_DEFER_TASKRUN)
io_move_task_work_from_local(ctx);
return NULL;
ifq->if_rxq = -1;
- ifq->ctx = ctx;
spin_lock_init(&ifq->rq_lock);
mutex_init(&ifq->pp_lock);
+ refcount_set(&ifq->refs, 1);
return ifq;
}
kfree(ifq);
}
+static void io_put_zcrx_ifq(struct io_zcrx_ifq *ifq)
+{
+ if (refcount_dec_and_test(&ifq->refs))
+ io_zcrx_ifq_free(ifq);
+}
+
struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ctx,
unsigned int id)
{
ifq = io_zcrx_ifq_alloc(ctx);
if (!ifq)
return -ENOMEM;
+
if (ctx->user) {
get_uid(ctx->user);
ifq->user = ctx->user;
}
}
-void io_shutdown_zcrx_ifqs(struct io_ring_ctx *ctx)
-{
- struct io_zcrx_ifq *ifq;
- unsigned long index;
-
- lockdep_assert_held(&ctx->uring_lock);
-
- xa_for_each(&ctx->zcrx_ctxs, index, ifq) {
- io_zcrx_scrub(ifq);
- io_close_queue(ifq);
- }
-}
-
void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx)
{
struct io_zcrx_ifq *ifq;
}
if (!ifq)
break;
- io_zcrx_ifq_free(ifq);
+
+ io_close_queue(ifq);
+ io_zcrx_scrub(ifq);
+ io_put_zcrx_ifq(ifq);
}
xa_destroy(&ctx->zcrx_ctxs);
if (ret)
return ret;
- percpu_ref_get(&ifq->ctx->refs);
+ refcount_inc(&ifq->refs);
return 0;
}
static void io_pp_zc_destroy(struct page_pool *pp)
{
- struct io_zcrx_ifq *ifq = io_pp_to_ifq(pp);
-
- percpu_ref_put(&ifq->ctx->refs);
+ io_put_zcrx_ifq(io_pp_to_ifq(pp));
}
static int io_pp_nl_fill(void *mp_priv, struct sk_buff *rsp,
};
struct io_zcrx_ifq {
- struct io_ring_ctx *ctx;
struct io_zcrx_area *area;
unsigned niov_shift;
struct user_struct *user;
struct device *dev;
struct net_device *netdev;
netdevice_tracker netdev_tracker;
+ refcount_t refs;
/*
* Page pool and net configuration lock, can be taken deeper in the
int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
struct io_uring_zcrx_ifq_reg __user *arg);
void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx);
-void io_shutdown_zcrx_ifqs(struct io_ring_ctx *ctx);
int io_zcrx_recv(struct io_kiocb *req, struct io_zcrx_ifq *ifq,
struct socket *sock, unsigned int flags,
unsigned issue_flags, unsigned int *len);
static inline void io_unregister_zcrx_ifqs(struct io_ring_ctx *ctx)
{
}
-static inline void io_shutdown_zcrx_ifqs(struct io_ring_ctx *ctx)
-{
-}
static inline int io_zcrx_recv(struct io_kiocb *req, struct io_zcrx_ifq *ifq,
struct socket *sock, unsigned int flags,
unsigned issue_flags, unsigned int *len)