]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - rt-patches/0098-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch
rt_patches: required rebase due to printk change
[hercules2020/nv-tegra/linux-4.4.git] / rt-patches / 0098-sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch
1 From 715edf6f96ba45dc4836d4e8b0e6c23701559db5 Mon Sep 17 00:00:00 2001
2 From: Steven Rostedt <rostedt@goodmis.org>
3 Date: Mon, 18 Mar 2013 15:12:49 -0400
4 Subject: [PATCH 098/366] sched/workqueue: Only wake up idle workers if not
5  blocked on sleeping spin lock
6
7 In -rt, most spin_locks() turn into mutexes. One of these spin_lock
8 conversions is performed on the workqueue gcwq->lock. When the idle
9 worker is worken, the first thing it will do is grab that same lock and
10 it too will block, possibly jumping into the same code, but because
11 nr_running would already be decremented it prevents an infinite loop.
12
13 But this is still a waste of CPU cycles, and it doesn't follow the method
14 of mainline, as new workers should only be woken when a worker thread is
15 truly going to sleep, and not just blocked on a spin_lock().
16
17 Check the saved_state too before waking up new workers.
18
19 Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
20 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
21 ---
22  kernel/sched/core.c | 4 +++-
23  1 file changed, 3 insertions(+), 1 deletion(-)
24
25 diff --git a/kernel/sched/core.c b/kernel/sched/core.c
26 index 0ea89e6..3fa109f 100644
27 --- a/kernel/sched/core.c
28 +++ b/kernel/sched/core.c
29 @@ -3363,8 +3363,10 @@ static void __sched notrace __schedule(bool preempt)
30                          * If a worker went to sleep, notify and ask workqueue
31                          * whether it wants to wake up a task to maintain
32                          * concurrency.
33 +                        * Only call wake up if prev isn't blocked on a sleeping
34 +                        * spin lock.
35                          */
36 -                       if (prev->flags & PF_WQ_WORKER) {
37 +                       if (prev->flags & PF_WQ_WORKER && !prev->saved_state) {
38                                 struct task_struct *to_wakeup;
39  
40                                 to_wakeup = wq_worker_sleeping(prev, cpu);
41 -- 
42 1.9.1
43