| From: Steven Rostedt <rostedt@goodmis.org> |
| Date: Mon, 18 Mar 2013 15:12:49 -0400 |
| Subject: 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> |
| --- |
| kernel/sched/core.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/kernel/sched/core.c |
| +++ b/kernel/sched/core.c |
| @@ -3482,8 +3482,10 @@ static void __sched notrace __schedule(b |
| * 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); |