mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 07:51:31 -04:00
workqueue: Add pool_workqueue to pending_pwqs list when unplugging multiple inactive works
In unplug_oldest_pwq(), the first inactive work item on the
pool_workqueue is activated correctly. However, if multiple inactive
works exist on the same pool_workqueue, subsequent works fail to
activate because wq_node_nr_active.pending_pwqs is empty — the list
insertion is skipped when the pool_workqueue is plugged.
Fix this by checking for additional inactive works in
unplug_oldest_pwq() and updating wq_node_nr_active.pending_pwqs
accordingly.
Fixes: 4c065dbce1 ("workqueue: Enable unbound cpumask update on ordered workqueues")
Cc: stable@vger.kernel.org
Cc: Carlos Santa <carlos.santa@intel.com>
Cc: Ryan Neph <ryanneph@google.com>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Waiman Long <longman@redhat.com>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Waiman Long <longman@redhat.com>
This commit is contained in:
@@ -1849,8 +1849,20 @@ static void unplug_oldest_pwq(struct workqueue_struct *wq)
|
||||
raw_spin_lock_irq(&pwq->pool->lock);
|
||||
if (pwq->plugged) {
|
||||
pwq->plugged = false;
|
||||
if (pwq_activate_first_inactive(pwq, true))
|
||||
if (pwq_activate_first_inactive(pwq, true)) {
|
||||
/*
|
||||
* While plugged, queueing skips activation which
|
||||
* includes bumping the nr_active count and adding the
|
||||
* pwq to nna->pending_pwqs if the count can't be
|
||||
* obtained. We need to restore both for the pwq being
|
||||
* unplugged. The first call activates the first
|
||||
* inactive work item and the second, if there are more
|
||||
* inactive, puts the pwq on pending_pwqs.
|
||||
*/
|
||||
pwq_activate_first_inactive(pwq, false);
|
||||
|
||||
kick_pool(pwq->pool);
|
||||
}
|
||||
}
|
||||
raw_spin_unlock_irq(&pwq->pool->lock);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user