summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-02-14 14:04:46 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2011-02-24 14:54:32 -0800
commit1257389b28b59639173c961b49fefe06820f6fb6 (patch)
treed3045e36a7fe586520a84c2a6ab424990f848421 /kernel
parentd72ffd63dfec63e7998533b867b5e27a0cb19ed7 (diff)
workqueue: wake up a worker when a rescuer is leaving a gcwq
commit 7576958a9d5a4a677ad7dd40901cdbb6c1110c98 upstream. After executing the matching works, a rescuer leaves the gcwq whether there are more pending works or not. This may decrease the concurrency level to zero and stall execution until a new work item is queued on the gcwq. Make rescuer wake up a regular worker when it leaves a gcwq if there are more works to execute, so that execution isn't stalled. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Ray Jui <rjui@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/workqueue.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 4be7fa5fe304..7a7ff509b551 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2009,6 +2009,15 @@ repeat:
move_linked_works(work, scheduled, &n);
process_scheduled_works(rescuer);
+
+ /*
+ * Leave this gcwq. If keep_working() is %true, notify a
+ * regular worker; otherwise, we end up with 0 concurrency
+ * and stalling the execution.
+ */
+ if (keep_working(gcwq))
+ wake_up_worker(gcwq);
+
spin_unlock_irq(&gcwq->lock);
}