diff options
| author | Tejun Heo <tj@kernel.org> | 2011-02-14 08:04:46 -0500 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2011-02-14 08:04:46 -0500 |
| commit | 7576958a9d5a4a677ad7dd40901cdbb6c1110c98 (patch) | |
| tree | db0b180feebf3a4ca6cd3155764cfc61a6d7f3cf | |
| parent | 795abaf1e4e188c4171e3cd3dbb11a9fcacaf505 (diff) | |
workqueue: wake up a worker when a rescuer is leaving a gcwq
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>
Cc: stable@kernel.org
| -rw-r--r-- | kernel/workqueue.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 11869faa6819..90a17ca2ad0b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
| @@ -2047,6 +2047,15 @@ repeat: | |||
| 2047 | move_linked_works(work, scheduled, &n); | 2047 | move_linked_works(work, scheduled, &n); |
| 2048 | 2048 | ||
| 2049 | process_scheduled_works(rescuer); | 2049 | process_scheduled_works(rescuer); |
| 2050 | |||
| 2051 | /* | ||
| 2052 | * Leave this gcwq. If keep_working() is %true, notify a | ||
| 2053 | * regular worker; otherwise, we end up with 0 concurrency | ||
| 2054 | * and stalling the execution. | ||
| 2055 | */ | ||
| 2056 | if (keep_working(gcwq)) | ||
| 2057 | wake_up_worker(gcwq); | ||
| 2058 | |||
| 2050 | spin_unlock_irq(&gcwq->lock); | 2059 | spin_unlock_irq(&gcwq->lock); |
| 2051 | } | 2060 | } |
| 2052 | 2061 | ||
