aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2013-03-18 15:12:49 -0400
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-02-13 00:34:57 +0100
commit15eb6958cd80815f1113489e3ccdc50d35368015 (patch)
tree114a96cdcdeccb98c2c30de1f1b3cc1dec7a84b3
parente2bca16cbfcd6b3b7b2199f21f6de2a8fffff9cd (diff)
downloadrt-linux-15eb6958cd80815f1113489e3ccdc50d35368015.tar.gz
sched/workqueue: Only wake up idle workers if not blocked on sleeping spin lock
In -rt, most spin_locks() turn into mutexes. One of these spin_lock conversions is performed on the workqueue gcwq->lock. When the idle worker is worken, the first thing it will do is grab that same lock and it too will block, possibly jumping into the same code, but because nr_running would already be decremented it prevents an infinite loop. But this is still a waste of CPU cycles, and it doesn't follow the method of mainline, as new workers should only be woken when a worker thread is truly going to sleep, and not just blocked on a spin_lock(). Check the saved_state too before waking up new workers. Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--kernel/sched/core.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 4bc051baf87de..83a64d4a80e53 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3264,8 +3264,10 @@ static void __sched notrace __schedule(bool preempt)
* If a worker went to sleep, notify and ask workqueue
* whether it wants to wake up a task to maintain
* concurrency.
+ * Only call wake up if prev isn't blocked on a sleeping
+ * spin lock.
*/
- if (prev->flags & PF_WQ_WORKER) {
+ if (prev->flags & PF_WQ_WORKER && !prev->saved_state) {
struct task_struct *to_wakeup;
to_wakeup = wq_worker_sleeping(prev, cpu);