Re: [PATCH] io_uring/io-wq: avoid repeated task_work scans during teardown
From: Jens Axboe
Date: Thu May 21 2026 - 13:08:21 EST
On 5/19/26 9:12 PM, Fengnan Chang wrote:
> We hit hard-lockup reports from iou-wrk threads stuck in
> task_work_cancel_match() during io-wq teardown in syzkaller test.
> The root cause is that teardown repeatedly rescans the submitter task's
> full task_work list under pi_lock, once per matched item.
>
> Two spots are problematic:
>
> 1) io_wq_cancel_tw_create() loops calling task_work_cancel_match() to
> remove worker-creation callbacks one at a time. Each call re-walks
> the entire list from scratch while holding pi_lock.
>
> 2) io_worker_exit() unconditionally scans the submitter task_work list
> for its own create_work, even when it never queued one. With many
> workers exiting simultaneously against a large unrelated task_work
> list, this adds up fast.
>
> Fix (1) by adding task_work_cancel_match_all() that unlinks all matching
> callbacks in a single traversal, then iterating the returned list locally.
> Same try_cmpxchg() synchronisation as before, stops at the work_exited
> sentinel.
>
> Fix (2) by skipping the cancel entirely unless create_state indicates a
> pending create_work. Since create_state is exclusively owned via
> test_and_set_bit_lock, at most one callback can be queued per worker, so
> the cancel is also simplified from a loop to a single call.
>
> With this fix the reproducer (FIFO-open + MSG_RING SEND_FD stress) no
> longer triggers hard-lockup reports, and task_work_cancel_match samples
> drop to microseconds.
Looks good to me, nicer way to do this too.
--
Jens Axboe