aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-01-12 08:12:44 -0500
committerIngo Molnar <mingo@kernel.org>2014-01-12 08:12:44 -0500
commitdba861461f88c12249ac78fb877866c04f99deb3 (patch)
tree5812b143581bcc66c7c542f01ba0cb22e489b8e5 /kernel/time
parent0e6601eee039893a3f6420596ae4588d90d13cbe (diff)
parent228fdc083b017eaf90e578fa86fb1ecfd5ffae87 (diff)
Merge branch 'linus' into timers/core
Pick up the latest fixes and refresh the branch. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/tick-common.c15
-rw-r--r--kernel/time/tick-sched.c25
-rw-r--r--kernel/time/timekeeping.c2
3 files changed, 28 insertions, 14 deletions
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 64522ecdfe0e..162b03ab0ad2 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -33,6 +33,21 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
33 */ 33 */
34ktime_t tick_next_period; 34ktime_t tick_next_period;
35ktime_t tick_period; 35ktime_t tick_period;
36
37/*
38 * tick_do_timer_cpu is a timer core internal variable which holds the CPU NR
39 * which is responsible for calling do_timer(), i.e. the timekeeping stuff. This
40 * variable has two functions:
41 *
42 * 1) Prevent a thundering herd issue of a gazillion of CPUs trying to grab the
43 * timekeeping lock all at once. Only the CPU which is assigned to do the
44 * update is handling it.
45 *
46 * 2) Hand off the duty in the NOHZ idle case by setting the value to
47 * TICK_DO_TIMER_NONE, i.e. a non existing CPU. So the next cpu which looks
48 * at it will take over and keep the time keeping alive. The handover
49 * procedure also covers cpu hotplug.
50 */
36int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT; 51int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
37 52
38/* 53/*
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 2afd43fca93b..52cee12b3302 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 */
@@ -461,7 +461,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
461 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 461 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
462 ktime_t now, idle; 462 ktime_t now, idle;
463 463
464 if (!tick_nohz_enabled) 464 if (!tick_nohz_active)
465 return -1; 465 return -1;
466 466
467 now = ktime_get(); 467 now = ktime_get();
@@ -502,7 +502,7 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
502 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 502 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
503 ktime_t now, iowait; 503 ktime_t now, iowait;
504 504
505 if (!tick_nohz_enabled) 505 if (!tick_nohz_active)
506 return -1; 506 return -1;
507 507
508 now = ktime_get(); 508 now = ktime_get();
@@ -707,8 +707,10 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
707 return false; 707 return false;
708 } 708 }
709 709
710 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) 710 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) {
711 ts->sleep_length = (ktime_t) { .tv64 = NSEC_PER_SEC/HZ };
711 return false; 712 return false;
713 }
712 714
713 if (need_resched()) 715 if (need_resched())
714 return false; 716 return false;
@@ -795,11 +797,6 @@ void tick_nohz_idle_enter(void)
795 local_irq_disable(); 797 local_irq_disable();
796 798
797 ts = &__get_cpu_var(tick_cpu_sched); 799 ts = &__get_cpu_var(tick_cpu_sched);
798 /*
799 * set ts->inidle unconditionally. even if the system did not
800 * switch to nohz mode the cpu frequency governers rely on the
801 * update of the idle time accounting in tick_nohz_start_idle().
802 */
803 ts->inidle = 1; 800 ts->inidle = 1;
804 __tick_nohz_idle_enter(ts); 801 __tick_nohz_idle_enter(ts);
805 802
@@ -968,7 +965,7 @@ static void tick_nohz_switch_to_nohz(void)
968 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); 965 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
969 ktime_t next; 966 ktime_t next;
970 967
971 if (!tick_nohz_enabled) 968 if (!tick_nohz_active)
972 return; 969 return;
973 970
974 local_irq_disable(); 971 local_irq_disable();
@@ -976,7 +973,7 @@ static void tick_nohz_switch_to_nohz(void)
976 local_irq_enable(); 973 local_irq_enable();
977 return; 974 return;
978 } 975 }
979 976 tick_nohz_active = 1;
980 ts->nohz_mode = NOHZ_MODE_LOWRES; 977 ts->nohz_mode = NOHZ_MODE_LOWRES;
981 978
982 /* 979 /*
@@ -1132,8 +1129,10 @@ void tick_setup_sched_timer(void)
1132 } 1129 }
1133 1130
1134#ifdef CONFIG_NO_HZ_COMMON 1131#ifdef CONFIG_NO_HZ_COMMON
1135 if (tick_nohz_enabled) 1132 if (tick_nohz_enabled) {
1136 ts->nohz_mode = NOHZ_MODE_HIGHRES; 1133 ts->nohz_mode = NOHZ_MODE_HIGHRES;
1134 tick_nohz_active = 1;
1135 }
1137#endif 1136#endif
1138} 1137}
1139#endif /* HIGH_RES_TIMERS */ 1138#endif /* HIGH_RES_TIMERS */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 3abf53418b67..87b4f00284c9 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1347,7 +1347,7 @@ static inline void old_vsyscall_fixup(struct timekeeper *tk)
1347 tk->xtime_nsec -= remainder; 1347 tk->xtime_nsec -= remainder;
1348 tk->xtime_nsec += 1ULL << tk->shift; 1348 tk->xtime_nsec += 1ULL << tk->shift;
1349 tk->ntp_error += remainder << tk->ntp_error_shift; 1349 tk->ntp_error += remainder << tk->ntp_error_shift;
1350 1350 tk->ntp_error -= (1ULL << tk->shift) << tk->ntp_error_shift;
1351} 1351}
1352#else 1352#else
1353#define old_vsyscall_fixup(tk) 1353#define old_vsyscall_fixup(tk)