Re: [PATCH] io_uring/io-wq: avoid repeated task_work scans during teardown
From: Gabriel Krisman Bertazi
Date: Wed May 20 2026 - 09:56:18 EST
"Fengnan Chang" <changfengnan@xxxxxxxxxxxxx> writes:
> We hit hard-lockup reports from iou-wrk threads stuck in
It seems like a soft-lockup instead no? From your description,
eventually it solves itself, the task is just uninterruptible while
contending on the spinlock.
> + */
> +struct callback_head *
> +task_work_cancel_match_all(struct task_struct *task,
> + bool (*match)(struct callback_head *, void *data),
> + void *data)
> +{
> + struct callback_head **pprev = &task->task_works;
> + struct callback_head *work, *next;
> + struct callback_head *head = NULL, **tail = &head;
> + unsigned long flags;
> +
> + if (likely(!task_work_pending(task)))
> + return NULL;
> +
> + raw_spin_lock_irqsave(&task->pi_lock, flags);
> + work = READ_ONCE(*pprev);
> + while (work && work != &work_exited) {
> + next = READ_ONCE(work->next);
> + if (!match(work, data)) {
> + pprev = &work->next;
> + work = next;
> + continue;
> + }
> +
> + if (!try_cmpxchg(pprev, &work, next))
> + continue;
IIUC, you could ignore the cmpxchg here because the following loop
iteration on the caller would catch it and retry. In this case, it no
retry in io_wq_cancel_tw_create, which looks weird. Did I miss something?
> +
> + work->next = NULL;
> + *tail = work;
> + tail = &work->next;
> + work = next;
> + }
> + raw_spin_unlock_irqrestore(&task->pi_lock, flags);
> +
> + return head;
> +}
> +
> static bool task_work_func_match(struct callback_head *cb, void *data)
> {
> return cb->func == data;
--
Gabriel Krisman Bertazi