When io_wq_exit_start() is called, the IO_WQ_BIT_EXIT bit is set to indicate to workers that the async context is going away. When that happens, any worker alive should be woken up. If that doesn't happen, then io-wq worker exit may take as long as WORKER_IDLE_TIMEOUT, which is set to 5 seconds by default. Cc: stable@vger.kernel.org # v6.18+ Signed-off-by: Jens Axboe --- Didn't fully bisect where this problem got introduced, it's sometime between 6.12 and 6.15. But as 6.18 is the latest maintained stable that has the issue, just mark it for 6.18. diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index cd13d8aac3d2..fd8c15ad2b97 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -1294,6 +1294,14 @@ static bool io_task_work_match(struct callback_head *cb, void *data) void io_wq_exit_start(struct io_wq *wq) { set_bit(IO_WQ_BIT_EXIT, &wq->state); + + for (int i = 0; i < IO_WQ_ACCT_NR; i++) { + struct io_wq_acct *acct = &wq->acct[i]; + + raw_spin_lock(&acct->workers_lock); + io_acct_for_each_worker(acct, io_wq_worker_wake, NULL); + raw_spin_unlock(&acct->workers_lock); + } } static void io_wq_cancel_tw_create(struct io_wq *wq) -- Jens Axboe