summaryrefslogtreecommitdiffstats
path: root/sched-Prevent-boosting-of-idle-task-on-rt.patch
blob: 21556951dde916b8b44245d1a572ddba6b2f676a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
From a8db0bb752df20ffb153a442d228e09cab65968e Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Fri, 3 Jul 2009 08:30:06 -0500
Subject: [PATCH] sched: Prevent boosting of idle task on -rt

commit 4ee888c3c41c562c6d575011cc4696bcddc2f956 in tip.

Idle task boosting is a nono in general. There is one exception, when
NOHZ is active:

The idle task calls get_next_timer_interrupt() and holds the timer
wheel base->lock on the CPU and another CPU wants to access the timer
(probably to cancel it). We can safely ignore the boosting request, as
the idle CPU runs this code with interrupts disabled and will complete
the lock protected section without being interrupted. So there is no
real need to boost.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 kernel/sched.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/kernel/sched.c b/kernel/sched.c
index d56e54d..29d4416 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4474,6 +4474,25 @@ void task_setprio(struct task_struct *p, int prio)
 	BUG_ON(prio < 0 || prio > MAX_PRIO);
 
 	rq = task_rq_lock(p, &flags);
+
+	/*
+	 * Idle task boosting is a nono in general. There is one
+	 * exception, when NOHZ is active:
+	 *
+	 * The idle task calls get_next_timer_interrupt() and holds
+	 * the timer wheel base->lock on the CPU and another CPU wants
+	 * to access the timer (probably to cancel it). We can safely
+	 * ignore the boosting request, as the idle CPU runs this code
+	 * with interrupts disabled and will complete the lock
+	 * protected section without being interrupted. So there is no
+	 * real need to boost.
+	 */
+	if (unlikely(p == rq->idle)) {
+		WARN_ON(p != rq->curr);
+		WARN_ON(p->pi_blocked_on);
+		goto out_unlock;
+	}
+
 	update_rq_clock(rq);
 
 	oldprio = p->prio;
@@ -4502,6 +4521,7 @@ void task_setprio(struct task_struct *p, int prio)
 		check_class_changed(rq, p, prev_class, oldprio, running);
 	}
 
+out_unlock:
 	task_rq_unlock(rq, &flags);
 }
 
-- 
1.7.0.4