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.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -1849,8 +1849,20 @@ static void unplug_oldest_pwq(struct workqueue_struct *wq) · 1848 unmodified lines | |||
| 1849 | raw_spin_lock_irq(&pwq->pool->lock); | 1849 | raw_spin_lock_irq(&pwq->pool->lock); |
| 1850 | if (pwq->plugged) { | 1850 | if (pwq->plugged) { |
| 1851 | pwq->plugged = false; | 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 | kick_pool(pwq->pool); | 1864 | kick_pool(pwq->pool); |
| 1865 | } | ||
| 1854 | } | 1866 | } |
| 1855 | raw_spin_unlock_irq(&pwq->pool->lock); | 1867 | raw_spin_unlock_irq(&pwq->pool->lock); |
| 1856 | } | 1868 | } |