aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-11-13 15:01:57 -0500
committerThomas Gleixner <tglx@linutronix.de>2013-11-19 08:59:50 -0500
commitd689fe222a858c767cb8594faf280048e532b53f (patch)
tree2ddb3ee24ce9fd2566a6fb9204ea9861a74a7404 /kernel/time
parent801a76050bcf8d4e500eb8d048ff6265f37a61c8 (diff)
NOHZ: Check for nohz active instead of nohz enabled
RCU and the fine grained idle time accounting functions check tick_nohz_enabled. But that variable is merily telling that NOHZ has been enabled in the config and not been disabled on the command line. But it does not tell anything about nohz being active. That's what all this should check for. Matthew reported, that the idle accounting on his old P1 machine showed bogus values, when he enabled NOHZ in the config and did not disable it on the kernel command line. The reason is that his machine uses (refined) jiffies as a clocksource which explains why the "fine" grained accounting went into lala land, because it depends on when the system goes and leaves idle relative to the jiffies increment. Provide a tick_nohz_active indicator and let RCU and the accounting code use this instead of tick_nohz_enable. Reported-and-tested-by: Matthew Whitehead <tedheadster@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Steven Rostedt <rostedt@goodmis.org> Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: john.stultz@linaro.org Cc: mwhitehe@redhat.com Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1311132052240.30673@ionos.tec.linutronix.de
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/tick-sched.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 3612fc77f834..a12df5abde0b 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -361,8 +361,8 @@ void __init tick_nohz_init(void)
361/* 361/*
362 * NO HZ enabled ? 362 * NO HZ enabled ?
363 */ 363 */
364int tick_nohz_enabled __read_mostly = 1; 364static int tick_nohz_enabled __read_mostly = 1;
365 365int tick_nohz_active __read_mostly;
366/* 366/*
367 * Enable / Disable tickless mode 367 * Enable / Disable tickless mode
368 */ 368 */
@@ -465,7 +465,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
465 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 465 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
466 ktime_t now, idle; 466 ktime_t now, idle;
467 467
468 if (!tick_nohz_enabled) 468 if (!tick_nohz_active)
469 return -1; 469 return -1;
470 470
471 now = ktime_get(); 471 now = ktime_get();
@@ -506,7 +506,7 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
506 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 506 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
507 ktime_t now, iowait; 507 ktime_t now, iowait;
508 508
509 if (!tick_nohz_enabled) 509 if (!tick_nohz_active)
510 return -1; 510 return -1;
511 511
512 now = ktime_get(); 512 now = ktime_get();
@@ -799,11 +799,6 @@ void tick_nohz_idle_enter(void)
799 local_irq_disable(); 799 local_irq_disable();
800 800
801 ts = &__get_cpu_var(tick_cpu_sched); 801 ts = &__get_cpu_var(tick_cpu_sched);
802 /*
803 * set ts->inidle unconditionally. even if the system did not
804 * switch to nohz mode the cpu frequency governers rely on the
805 * update of the idle time accounting in tick_nohz_start_idle().
806 */
807 ts->inidle = 1; 802 ts->inidle = 1;
808 __tick_nohz_idle_enter(ts); 803 __tick_nohz_idle_enter(ts);
809 804
@@ -973,7 +968,7 @@ static void tick_nohz_switch_to_nohz(void)
973 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); 968 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
974 ktime_t next; 969 ktime_t next;
975 970
976 if (!tick_nohz_enabled) 971 if (!tick_nohz_active)
977 return; 972 return;
978 973
979 local_irq_disable(); 974 local_irq_disable();
@@ -981,7 +976,7 @@ static void tick_nohz_switch_to_nohz(void)
981 local_irq_enable(); 976 local_irq_enable();
982 return; 977 return;
983 } 978 }
984 979 tick_nohz_active = 1;
985 ts->nohz_mode = NOHZ_MODE_LOWRES; 980 ts->nohz_mode = NOHZ_MODE_LOWRES;
986 981
987 /* 982 /*
@@ -1139,8 +1134,10 @@ void tick_setup_sched_timer(void)
1139 } 1134 }
1140 1135
1141#ifdef CONFIG_NO_HZ_COMMON 1136#ifdef CONFIG_NO_HZ_COMMON
1142 if (tick_nohz_enabled) 1137 if (tick_nohz_enabled) {
1143 ts->nohz_mode = NOHZ_MODE_HIGHRES; 1138 ts->nohz_mode = NOHZ_MODE_HIGHRES;
1139 tick_nohz_active = 1;
1140 }
1144#endif 1141#endif
1145} 1142}
1146#endif /* HIGH_RES_TIMERS */ 1143#endif /* HIGH_RES_TIMERS */