io_uring: allow io-wq workers to exit when unused

io_uring keeps a per-task io-wq around, even when the task no longer has
any io_uring instances.

If the task previously used io_uring for file I/O, this can leave an
unrelated iou-wrk-* worker thread behind after the last io_uring
instance is gone.

When the last io_uring ctx is removed from the task context, mark the
io-wq exit-on-idle so workers can go away. Clear the flag on subsequent
io_uring usage.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
Li Chen
2026-02-02 22:37:54 +08:00
committed by Jens Axboe
parent 38aa434ab9
commit 9121466148

View File

@@ -122,6 +122,14 @@ int __io_uring_add_tctx_node(struct io_ring_ctx *ctx)
return ret;
}
}
/*
* Re-activate io-wq keepalive on any new io_uring usage. The wq may have
* been marked for idle-exit when the task temporarily had no active
* io_uring instances.
*/
if (tctx->io_wq)
io_wq_set_exit_on_idle(tctx->io_wq, false);
if (!xa_load(&tctx->xa, (unsigned long)ctx)) {
node = kmalloc(sizeof(*node), GFP_KERNEL);
if (!node)
@@ -183,6 +191,9 @@ __cold void io_uring_del_tctx_node(unsigned long index)
if (tctx->last == node->ctx)
tctx->last = NULL;
kfree(node);
if (xa_empty(&tctx->xa) && tctx->io_wq)
io_wq_set_exit_on_idle(tctx->io_wq, true);
}
__cold void io_uring_clean_tctx(struct io_uring_task *tctx)