sched/rt: Keep period timer ticking when rt throttling is active
authorPeter Zijlstra <peterz@infradead.org>
Tue, 18 Oct 2011 20:03:48 +0000 (22:03 +0200)
committerIngo Molnar <mingo@elte.hu>
Thu, 1 Mar 2012 09:28:01 +0000 (10:28 +0100)
When a runqueue is throttled we cannot disable the period timer
because that timer is the only way to undo the throttling.

We got stale throttling entries when a rq was throttled and then the
global sysctl was disabled, which stopped the timer.

Signed-off-by: Peter Zijlstra <peterz@infradead.org>
[ Added changelog ]
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/n/tip-nuj34q52p6ro7szapuz84i0v@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@elte.hu>
kernel/sched/rt.c

index f70206c..6d1eb0b 100644 (file)
@@ -778,12 +778,9 @@ static inline int balance_runtime(struct rt_rq *rt_rq)
 
 static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
 {
-       int i, idle = 1;
+       int i, idle = 1, throttled = 0;
        const struct cpumask *span;
 
-       if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)
-               return 1;
-
        span = sched_rt_period_mask();
        for_each_cpu(i, span) {
                int enqueue = 0;
@@ -818,12 +815,17 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
                        if (!rt_rq_throttled(rt_rq))
                                enqueue = 1;
                }
+               if (rt_rq->rt_throttled)
+                       throttled = 1;
 
                if (enqueue)
                        sched_rt_rq_enqueue(rt_rq);
                raw_spin_unlock(&rq->lock);
        }
 
+       if (!throttled && (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF))
+               return 1;
+
        return idle;
 }
 
@@ -884,7 +886,8 @@ static void update_curr_rt(struct rq *rq)
        if (unlikely((s64)delta_exec < 0))
                delta_exec = 0;
 
-       schedstat_set(curr->se.statistics.exec_max, max(curr->se.statistics.exec_max, delta_exec));
+       schedstat_set(curr->se.statistics.exec_max,
+                     max(curr->se.statistics.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
        account_group_exec_runtime(curr, delta_exec);