aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
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
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')
-rw-r--r--kernel/rcu/tree_plugin.h4
-rw-r--r--kernel/time/tick-sched.c21
2 files changed, 11 insertions, 14 deletions
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index 6abb03dff5c0..08a765232432 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -1632,7 +1632,7 @@ module_param(rcu_idle_gp_delay, int, 0644);
1632static int rcu_idle_lazy_gp_delay = RCU_IDLE_LAZY_GP_DELAY; 1632static int rcu_idle_lazy_gp_delay = RCU_IDLE_LAZY_GP_DELAY;
1633module_param(rcu_idle_lazy_gp_delay, int, 0644); 1633module_param(rcu_idle_lazy_gp_delay, int, 0644);
1634 1634
1635extern int tick_nohz_enabled; 1635extern int tick_nohz_active;
1636 1636
1637/* 1637/*
1638 * Try to advance callbacks for all flavors of RCU on the current CPU, but 1638 * Try to advance callbacks for all flavors of RCU on the current CPU, but
@@ -1729,7 +1729,7 @@ static void rcu_prepare_for_idle(int cpu)
1729 int tne; 1729 int tne;
1730 1730
1731 /* Handle nohz enablement switches conservatively. */ 1731 /* Handle nohz enablement switches conservatively. */
1732 tne = ACCESS_ONCE(tick_nohz_enabled); 1732 tne = ACCESS_ONCE(tick_nohz_active);
1733 if (tne != rdtp->tick_nohz_enabled_snap) { 1733 if (tne != rdtp->tick_nohz_enabled_snap) {
1734 if (rcu_cpu_has_callbacks(cpu, NULL)) 1734 if (rcu_cpu_has_callbacks(cpu, NULL))
1735 invoke_rcu_core(); /* force nohz to see update. */ 1735 invoke_rcu_core(); /* force nohz to see update. */
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 */