Re: [PATCH] io_uring/io-wq: avoid repeated task_work scans during teardown

From: changfengnan

Date: Thu Jul 09 2026 - 05:16:42 EST


Ping.

> From: "changfengnan"<changfengnan@xxxxxxxxxxxxx>
> Date:  Mon, Jun 15, 2026, 15:33
> Subject:  Re: [PATCH] io_uring/io-wq: avoid repeated task_work scans during teardown
> To: "peterz"<peterz@xxxxxxxxxxxxx>, "rostedt"<rostedt@xxxxxxxxxxx>
> Cc: "io-uring"<io-uring@xxxxxxxxxxxxxxx>, "linux-kernel"<linux-kernel@xxxxxxxxxxxxxxx>, "axboe"<axboe@xxxxxxxxx>
> Hi Peter & Steven:
> Do you have time to help review this patch ?
> 
> Thanks.
> 
> 
> > From: "Jens Axboe"<axboe@xxxxxxxxx>
> > Date:  Fri, May 22, 2026, 00:59
> > Subject:  Re: [PATCH] io_uring/io-wq: avoid repeated task_work scans during teardown
> > To: "Fengnan Chang"<changfengnan@xxxxxxxxxxxxx>, <io-uring@xxxxxxxxxxxxxxx>, <linux-kernel@xxxxxxxxxxxxxxx>, <peterz@xxxxxxxxxxxxx>, <rostedt@xxxxxxxxxxx>
> > 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
>