[PATCH v1 2/2] io_uring: allow io-wq workers to exit when unused

Li Chen posted 2 patches 6 days, 23 hours ago
[PATCH v1 2/2] io_uring: allow io-wq workers to exit when unused
Posted by Li Chen 6 days, 23 hours ago
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>
---
 io_uring/tctx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/io_uring/tctx.c b/io_uring/tctx.c
index adc6e42c14df..8c6a4c56f5ec 100644
--- a/io_uring/tctx.c
+++ b/io_uring/tctx.c
@@ -124,6 +124,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)
@@ -185,6 +193,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)
-- 
2.52.0