Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: 4c065dbce1e8 ("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>

authored by

Matthew Brost and committed by
Tejun Heo
703ccb63 e398978d

+13 -1
+13 -1
kernel/workqueue.c
··· 1849 1849 raw_spin_lock_irq(&pwq->pool->lock); 1850 1850 if (pwq->plugged) { 1851 1851 pwq->plugged = false; 1852 - if (pwq_activate_first_inactive(pwq, true)) 1852 + if (pwq_activate_first_inactive(pwq, true)) { 1853 + /* 1854 + * While plugged, queueing skips activation which 1855 + * includes bumping the nr_active count and adding the 1856 + * pwq to nna->pending_pwqs if the count can't be 1857 + * obtained. We need to restore both for the pwq being 1858 + * unplugged. The first call activates the first 1859 + * inactive work item and the second, if there are more 1860 + * inactive, puts the pwq on pending_pwqs. 1861 + */ 1862 + pwq_activate_first_inactive(pwq, false); 1863 + 1853 1864 kick_pool(pwq->pool); 1865 + } 1854 1866 } 1855 1867 raw_spin_unlock_irq(&pwq->pool->lock); 1856 1868 }