diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r-- | kernel/time/tick-sched.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 6fa52cd6df0b..f4ee1a3428ae 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -121,10 +121,16 @@ static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now) | |||
121 | * into a long sleep. If two CPUs happen to assign themselves to | 121 | * into a long sleep. If two CPUs happen to assign themselves to |
122 | * this duty, then the jiffies update is still serialized by | 122 | * this duty, then the jiffies update is still serialized by |
123 | * jiffies_lock. | 123 | * jiffies_lock. |
124 | * | ||
125 | * If nohz_full is enabled, this should not happen because the | ||
126 | * tick_do_timer_cpu never relinquishes. | ||
124 | */ | 127 | */ |
125 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE) | 128 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) { |
126 | && !tick_nohz_full_cpu(cpu)) | 129 | #ifdef CONFIG_NO_HZ_FULL |
130 | WARN_ON(tick_nohz_full_running); | ||
131 | #endif | ||
127 | tick_do_timer_cpu = cpu; | 132 | tick_do_timer_cpu = cpu; |
133 | } | ||
128 | #endif | 134 | #endif |
129 | 135 | ||
130 | /* Check, if the jiffies need an update */ | 136 | /* Check, if the jiffies need an update */ |
@@ -395,8 +401,8 @@ void __init tick_nohz_full_setup(cpumask_var_t cpumask) | |||
395 | static int tick_nohz_cpu_down(unsigned int cpu) | 401 | static int tick_nohz_cpu_down(unsigned int cpu) |
396 | { | 402 | { |
397 | /* | 403 | /* |
398 | * The boot CPU handles housekeeping duty (unbound timers, | 404 | * The tick_do_timer_cpu CPU handles housekeeping duty (unbound |
399 | * workqueues, timekeeping, ...) on behalf of full dynticks | 405 | * timers, workqueues, timekeeping, ...) on behalf of full dynticks |
400 | * CPUs. It must remain online when nohz full is enabled. | 406 | * CPUs. It must remain online when nohz full is enabled. |
401 | */ | 407 | */ |
402 | if (tick_nohz_full_running && tick_do_timer_cpu == cpu) | 408 | if (tick_nohz_full_running && tick_do_timer_cpu == cpu) |
@@ -423,12 +429,15 @@ void __init tick_nohz_init(void) | |||
423 | return; | 429 | return; |
424 | } | 430 | } |
425 | 431 | ||
426 | cpu = smp_processor_id(); | 432 | if (IS_ENABLED(CONFIG_PM_SLEEP_SMP) && |
433 | !IS_ENABLED(CONFIG_PM_SLEEP_SMP_NONZERO_CPU)) { | ||
434 | cpu = smp_processor_id(); | ||
427 | 435 | ||
428 | if (cpumask_test_cpu(cpu, tick_nohz_full_mask)) { | 436 | if (cpumask_test_cpu(cpu, tick_nohz_full_mask)) { |
429 | pr_warn("NO_HZ: Clearing %d from nohz_full range for timekeeping\n", | 437 | pr_warn("NO_HZ: Clearing %d from nohz_full range " |
430 | cpu); | 438 | "for timekeeping\n", cpu); |
431 | cpumask_clear_cpu(cpu, tick_nohz_full_mask); | 439 | cpumask_clear_cpu(cpu, tick_nohz_full_mask); |
440 | } | ||
432 | } | 441 | } |
433 | 442 | ||
434 | for_each_cpu(cpu, tick_nohz_full_mask) | 443 | for_each_cpu(cpu, tick_nohz_full_mask) |
@@ -645,7 +654,8 @@ static inline bool local_timer_softirq_pending(void) | |||
645 | static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu) | 654 | static ktime_t tick_nohz_next_event(struct tick_sched *ts, int cpu) |
646 | { | 655 | { |
647 | u64 basemono, next_tick, next_tmr, next_rcu, delta, expires; | 656 | u64 basemono, next_tick, next_tmr, next_rcu, delta, expires; |
648 | unsigned long seq, basejiff; | 657 | unsigned long basejiff; |
658 | unsigned int seq; | ||
649 | 659 | ||
650 | /* Read jiffies and the time when jiffies were updated last */ | 660 | /* Read jiffies and the time when jiffies were updated last */ |
651 | do { | 661 | do { |
@@ -904,8 +914,13 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts) | |||
904 | /* | 914 | /* |
905 | * Boot safety: make sure the timekeeping duty has been | 915 | * Boot safety: make sure the timekeeping duty has been |
906 | * assigned before entering dyntick-idle mode, | 916 | * assigned before entering dyntick-idle mode, |
917 | * tick_do_timer_cpu is TICK_DO_TIMER_BOOT | ||
907 | */ | 918 | */ |
908 | if (tick_do_timer_cpu == TICK_DO_TIMER_NONE) | 919 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_BOOT)) |
920 | return false; | ||
921 | |||
922 | /* Should not happen for nohz-full */ | ||
923 | if (WARN_ON_ONCE(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) | ||
909 | return false; | 924 | return false; |
910 | } | 925 | } |
911 | 926 | ||
@@ -1023,6 +1038,18 @@ bool tick_nohz_idle_got_tick(void) | |||
1023 | } | 1038 | } |
1024 | 1039 | ||
1025 | /** | 1040 | /** |
1041 | * tick_nohz_get_next_hrtimer - return the next expiration time for the hrtimer | ||
1042 | * or the tick, whatever that expires first. Note that, if the tick has been | ||
1043 | * stopped, it returns the next hrtimer. | ||
1044 | * | ||
1045 | * Called from power state control code with interrupts disabled | ||
1046 | */ | ||
1047 | ktime_t tick_nohz_get_next_hrtimer(void) | ||
1048 | { | ||
1049 | return __this_cpu_read(tick_cpu_device.evtdev)->next_event; | ||
1050 | } | ||
1051 | |||
1052 | /** | ||
1026 | * tick_nohz_get_sleep_length - return the expected length of the current sleep | 1053 | * tick_nohz_get_sleep_length - return the expected length of the current sleep |
1027 | * @delta_next: duration until the next event if the tick cannot be stopped | 1054 | * @delta_next: duration until the next event if the tick cannot be stopped |
1028 | * | 1055 | * |