diff options
| author | Josef Bacik <josef@toxicpanda.com> | 2026-10-08 02:48:45 +0000 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2026-10-28 10:49:51 -0600 |
| commit | 47c68f925062a6013235d06add85a59f7d91e0fb (patch) | |
| tree | d3215fb4c93c636f7e5ffab4009cf26d61b40dfb /tools/lib/python | |
| parent | 2295613cd3713beffc8665e956135a5d48dfc208 (diff) | |
io_uring/io-wq: no new workers once the exit has begun
io_wq_exit_start() sets IO_WQ_BIT_EXIT, but worker creation task_work
queued before that stays queued until io_wq_exit_workers() cancels it.
In between the task runs its task_work while canceling requests, and a
worker can still get created.
That's a problem for exec. begin_new_exec() calls io_uring_task_cancel()
after de_thread(), when it's supposedly the only thread left, and
io_wq_exit_workers() only waits for ->worker_done, which a worker
completes before do_exit(). So the exiting worker is still in the thread
group, using the mm, files and sighand, while exec replaces them. Easy
to hit with a signal pending when create_io_thread() fails and the retry
gets queued right before execve().
Cancel the queued creation task_work as soon as the exit bit is set.
Pending work that isn't otherwise canceled now ends with -ECANCELED when
the io-wq is destroyed, rather than depending on whether the task
happened to run its task_work first.
Fixes: 685fe7feedb9 ("io-wq: eliminate the need for a manager thread")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[axboe: the barrier is already upstream, see 0e5663856b69, only the
cancel is new]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'tools/lib/python')
0 files changed, 0 insertions, 0 deletions
