Skip to content
This repository has been archived by the owner on Aug 14, 2023. It is now read-only.

Commit

Permalink
io_uring: complete notifiers in tw
Browse files Browse the repository at this point in the history
We need a task context to post CQEs but using wq is too expensive.
Try to complete notifiers using task_work and fall back to wq if fails.

Signed-off-by: Pavel Begunkov <[email protected]>
Link: https://lore.kernel.org/r/089799ab665b10b78fdc614ae6d59fa7ef0d5f91.1657643355.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
isilence authored and axboe committed Jul 25, 2022
1 parent eb4a299 commit e58d498
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
22 changes: 19 additions & 3 deletions io_uring/notif.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ static void __io_notif_complete_tw(struct callback_head *cb)
struct io_notif *notif = container_of(cb, struct io_notif, task_work);
struct io_ring_ctx *ctx = notif->ctx;

if (likely(notif->task)) {
io_put_task(notif->task, 1);
notif->task = NULL;
}

io_cq_lock(ctx);
io_fill_cqe_aux(ctx, notif->tag, 0, notif->seq, true);

Expand Down Expand Up @@ -43,6 +48,14 @@ static void io_uring_tx_zerocopy_callback(struct sk_buff *skb,

if (!refcount_dec_and_test(&uarg->refcnt))
return;

if (likely(notif->task)) {
init_task_work(&notif->task_work, __io_notif_complete_tw);
if (likely(!task_work_add(notif->task, &notif->task_work,
TWA_SIGNAL)))
return;
}

INIT_WORK(&notif->commit_work, io_notif_complete_wq);
queue_work(system_unbound_wq, &notif->commit_work);
}
Expand Down Expand Up @@ -134,12 +147,15 @@ __cold int io_notif_unregister(struct io_ring_ctx *ctx)
for (i = 0; i < ctx->nr_notif_slots; i++) {
struct io_notif_slot *slot = &ctx->notif_slots[i];

if (slot->notif)
io_notif_slot_flush(slot);
if (!slot->notif)
continue;
if (WARN_ON_ONCE(slot->notif->task))
slot->notif->task = NULL;
io_notif_slot_flush(slot);
}

kvfree(ctx->notif_slots);
ctx->notif_slots = NULL;
ctx->nr_notif_slots = 0;
return 0;
}
}
3 changes: 3 additions & 0 deletions io_uring/notif.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ struct io_notif {
struct ubuf_info uarg;
struct io_ring_ctx *ctx;

/* complete via tw if ->task is non-NULL, fallback to wq otherwise */
struct task_struct *task;

/* cqe->user_data, io_notif_slot::tag if not overridden */
u64 tag;
/* see struct io_notif_slot::seq */
Expand Down

0 comments on commit e58d498

Please sign in to comment.