aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r--kernel/time/tick-sched.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index ea20f7d1ac2c..9f8af69c67ec 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -86,6 +86,7 @@ static void tick_do_update_jiffies64(ktime_t now)
86 tick_next_period = ktime_add(last_jiffies_update, tick_period); 86 tick_next_period = ktime_add(last_jiffies_update, tick_period);
87 } 87 }
88 write_sequnlock(&jiffies_lock); 88 write_sequnlock(&jiffies_lock);
89 update_wall_time();
89} 90}
90 91
91/* 92/*
@@ -177,7 +178,7 @@ static bool can_stop_full_tick(void)
177 * TODO: kick full dynticks CPUs when 178 * TODO: kick full dynticks CPUs when
178 * sched_clock_stable is set. 179 * sched_clock_stable is set.
179 */ 180 */
180 if (!sched_clock_stable) { 181 if (!sched_clock_stable()) {
181 trace_tick_stop(0, "unstable sched clock\n"); 182 trace_tick_stop(0, "unstable sched clock\n");
182 /* 183 /*
183 * Don't allow the user to think they can get 184 * Don't allow the user to think they can get
@@ -391,11 +392,9 @@ __setup("nohz=", setup_tick_nohz);
391 */ 392 */
392static void tick_nohz_update_jiffies(ktime_t now) 393static void tick_nohz_update_jiffies(ktime_t now)
393{ 394{
394 int cpu = smp_processor_id();
395 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
396 unsigned long flags; 395 unsigned long flags;
397 396
398 ts->idle_waketime = now; 397 __this_cpu_write(tick_cpu_sched.idle_waketime, now);
399 398
400 local_irq_save(flags); 399 local_irq_save(flags);
401 tick_do_update_jiffies64(now); 400 tick_do_update_jiffies64(now);
@@ -426,17 +425,15 @@ update_ts_time_stats(int cpu, struct tick_sched *ts, ktime_t now, u64 *last_upda
426 425
427} 426}
428 427
429static void tick_nohz_stop_idle(int cpu, ktime_t now) 428static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)
430{ 429{
431 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 430 update_ts_time_stats(smp_processor_id(), ts, now, NULL);
432
433 update_ts_time_stats(cpu, ts, now, NULL);
434 ts->idle_active = 0; 431 ts->idle_active = 0;
435 432
436 sched_clock_idle_wakeup_event(0); 433 sched_clock_idle_wakeup_event(0);
437} 434}
438 435
439static ktime_t tick_nohz_start_idle(int cpu, struct tick_sched *ts) 436static ktime_t tick_nohz_start_idle(struct tick_sched *ts)
440{ 437{
441 ktime_t now = ktime_get(); 438 ktime_t now = ktime_get();
442 439
@@ -536,12 +533,13 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
536 struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; 533 struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
537 u64 time_delta; 534 u64 time_delta;
538 535
536 time_delta = timekeeping_max_deferment();
537
539 /* Read jiffies and the time when jiffies were updated last */ 538 /* Read jiffies and the time when jiffies were updated last */
540 do { 539 do {
541 seq = read_seqbegin(&jiffies_lock); 540 seq = read_seqbegin(&jiffies_lock);
542 last_update = last_jiffies_update; 541 last_update = last_jiffies_update;
543 last_jiffies = jiffies; 542 last_jiffies = jiffies;
544 time_delta = timekeeping_max_deferment();
545 } while (read_seqretry(&jiffies_lock, seq)); 543 } while (read_seqretry(&jiffies_lock, seq));
546 544
547 if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || 545 if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) ||
@@ -681,18 +679,18 @@ out:
681static void tick_nohz_full_stop_tick(struct tick_sched *ts) 679static void tick_nohz_full_stop_tick(struct tick_sched *ts)
682{ 680{
683#ifdef CONFIG_NO_HZ_FULL 681#ifdef CONFIG_NO_HZ_FULL
684 int cpu = smp_processor_id(); 682 int cpu = smp_processor_id();
685 683
686 if (!tick_nohz_full_cpu(cpu) || is_idle_task(current)) 684 if (!tick_nohz_full_cpu(cpu) || is_idle_task(current))
687 return; 685 return;
688 686
689 if (!ts->tick_stopped && ts->nohz_mode == NOHZ_MODE_INACTIVE) 687 if (!ts->tick_stopped && ts->nohz_mode == NOHZ_MODE_INACTIVE)
690 return; 688 return;
691 689
692 if (!can_stop_full_tick()) 690 if (!can_stop_full_tick())
693 return; 691 return;
694 692
695 tick_nohz_stop_sched_tick(ts, ktime_get(), cpu); 693 tick_nohz_stop_sched_tick(ts, ktime_get(), cpu);
696#endif 694#endif
697} 695}
698 696
@@ -754,7 +752,7 @@ static void __tick_nohz_idle_enter(struct tick_sched *ts)
754 ktime_t now, expires; 752 ktime_t now, expires;
755 int cpu = smp_processor_id(); 753 int cpu = smp_processor_id();
756 754
757 now = tick_nohz_start_idle(cpu, ts); 755 now = tick_nohz_start_idle(ts);
758 756
759 if (can_stop_idle_tick(cpu, ts)) { 757 if (can_stop_idle_tick(cpu, ts)) {
760 int was_stopped = ts->tick_stopped; 758 int was_stopped = ts->tick_stopped;
@@ -911,8 +909,7 @@ static void tick_nohz_account_idle_ticks(struct tick_sched *ts)
911 */ 909 */
912void tick_nohz_idle_exit(void) 910void tick_nohz_idle_exit(void)
913{ 911{
914 int cpu = smp_processor_id(); 912 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
915 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
916 ktime_t now; 913 ktime_t now;
917 914
918 local_irq_disable(); 915 local_irq_disable();
@@ -925,7 +922,7 @@ void tick_nohz_idle_exit(void)
925 now = ktime_get(); 922 now = ktime_get();
926 923
927 if (ts->idle_active) 924 if (ts->idle_active)
928 tick_nohz_stop_idle(cpu, now); 925 tick_nohz_stop_idle(ts, now);
929 926
930 if (ts->tick_stopped) { 927 if (ts->tick_stopped) {
931 tick_nohz_restart_sched_tick(ts, now); 928 tick_nohz_restart_sched_tick(ts, now);
@@ -1009,12 +1006,10 @@ static void tick_nohz_switch_to_nohz(void)
1009 * timer and do not touch the other magic bits which need to be done 1006 * timer and do not touch the other magic bits which need to be done
1010 * when idle is left. 1007 * when idle is left.
1011 */ 1008 */
1012static void tick_nohz_kick_tick(int cpu, ktime_t now) 1009static void tick_nohz_kick_tick(struct tick_sched *ts, ktime_t now)
1013{ 1010{
1014#if 0 1011#if 0
1015 /* Switch back to 2.6.27 behaviour */ 1012 /* Switch back to 2.6.27 behaviour */
1016
1017 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
1018 ktime_t delta; 1013 ktime_t delta;
1019 1014
1020 /* 1015 /*
@@ -1029,36 +1024,36 @@ static void tick_nohz_kick_tick(int cpu, ktime_t now)
1029#endif 1024#endif
1030} 1025}
1031 1026
1032static inline void tick_check_nohz(int cpu) 1027static inline void tick_nohz_irq_enter(void)
1033{ 1028{
1034 struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); 1029 struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
1035 ktime_t now; 1030 ktime_t now;
1036 1031
1037 if (!ts->idle_active && !ts->tick_stopped) 1032 if (!ts->idle_active && !ts->tick_stopped)
1038 return; 1033 return;
1039 now = ktime_get(); 1034 now = ktime_get();
1040 if (ts->idle_active) 1035 if (ts->idle_active)
1041 tick_nohz_stop_idle(cpu, now); 1036 tick_nohz_stop_idle(ts, now);
1042 if (ts->tick_stopped) { 1037 if (ts->tick_stopped) {
1043 tick_nohz_update_jiffies(now); 1038 tick_nohz_update_jiffies(now);
1044 tick_nohz_kick_tick(cpu, now); 1039 tick_nohz_kick_tick(ts, now);
1045 } 1040 }
1046} 1041}
1047 1042
1048#else 1043#else
1049 1044
1050static inline void tick_nohz_switch_to_nohz(void) { } 1045static inline void tick_nohz_switch_to_nohz(void) { }
1051static inline void tick_check_nohz(int cpu) { } 1046static inline void tick_nohz_irq_enter(void) { }
1052 1047
1053#endif /* CONFIG_NO_HZ_COMMON */ 1048#endif /* CONFIG_NO_HZ_COMMON */
1054 1049
1055/* 1050/*
1056 * Called from irq_enter to notify about the possible interruption of idle() 1051 * Called from irq_enter to notify about the possible interruption of idle()
1057 */ 1052 */
1058void tick_check_idle(int cpu) 1053void tick_irq_enter(void)
1059{ 1054{
1060 tick_check_oneshot_broadcast(cpu); 1055 tick_check_oneshot_broadcast_this_cpu();
1061 tick_check_nohz(cpu); 1056 tick_nohz_irq_enter();
1062} 1057}
1063 1058
1064/* 1059/*