Re: [PATCHSET wq/for-7.4] workqueue: Make flush_workqueue() cost scale with active pwqs

From: Breno Leitao

Date: Wed Sep 09 2026 - 06:46:35 EST


On Tue, Sep 01, 2026 at 11:09:26AM -1000, Tejun Heo wrote:
> Hello,
>
> Since 636b927eba5b ("workqueue: Make unbound workqueues to use per-cpu
> pool_workqueues"), flush_workqueue() walks one pwq per possible CPU, cycling
> each pool lock, even when the workqueue is idle. Yao Kai reported the XFS
> CIL workqueue, flushed on every log force, spending up to 64us per flush in
> that walk on a 128-CPU machine.

The problem seems clear to me. Flushing a PER_CPU workqueue, mean we
__flush_workqueue() -> flush_workqueue_prep_pwqs(), and then it cycle
through every pwq (one per possible CPU). This is all done with
wq->mutex.

Then, with the lock, we update the new color for the pool.

So, the locking context here is:

mutex_lock(wq->mutex)
for_each_pwq(pwq, wq) {
raw_spin_lock_irq(&current_pool->lock);
pwq->work_color = work_color;
raw_spin_unlock_irq(&current_pool->lock);
}

This all makes sense. I understand that, we need(ed) to do it, in order
to keep the work_color up-to-date. Let me read the patch now and see how
you've addressed that.

Thanks for copying me,
--breno