Re: [PATCH] io_uring/io-wq: avoid repeated task_work scans during teardown
Gabriel Krisman Bertazi <[email protected]>
| Newsgroups | org.kernel.vger.io-uring,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
"Fengnan Chang" <[email protected]> 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