16 #include <linux/hrtimer.h>
21 #include <linux/sched.h>
22 #include <linux/module.h>
24 #include <asm/irq_regs.h>
36 static ktime_t last_jiffies_update;
40 return &
per_cpu(tick_cpu_sched, cpu);
46 static void tick_do_update_jiffies64(
ktime_t now)
48 unsigned long ticks = 0;
54 delta = ktime_sub(now, last_jiffies_update);
59 write_seqlock(&xtime_lock);
61 delta = ktime_sub(now, last_jiffies_update);
65 last_jiffies_update = ktime_add(last_jiffies_update,
82 write_sequnlock(&xtime_lock);
88 static ktime_t tick_init_jiffy_update(
void)
92 write_seqlock(&xtime_lock);
94 if (last_jiffies_update.
tv64 == 0)
96 period = last_jiffies_update;
97 write_sequnlock(&xtime_lock);
113 static int __init setup_tick_nohz(
char *
str)
116 tick_nohz_enabled = 0;
117 else if (!
strcmp(str,
"on"))
118 tick_nohz_enabled = 1;
124 __setup(
"nohz=", setup_tick_nohz);
136 static void tick_nohz_update_jiffies(
ktime_t now)
139 struct tick_sched *
ts = &
per_cpu(tick_cpu_sched, cpu);
142 ts->idle_waketime = now;
145 tick_do_update_jiffies64(now);
155 update_ts_time_stats(
int cpu,
struct tick_sched *
ts,
ktime_t now,
u64 *last_update_time)
159 if (ts->idle_active) {
160 delta = ktime_sub(now, ts->idle_entrytime);
162 ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta);
164 ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
165 ts->idle_entrytime = now;
168 if (last_update_time)
169 *last_update_time = ktime_to_us(now);
173 static void tick_nohz_stop_idle(
int cpu,
ktime_t now)
175 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
177 update_ts_time_stats(cpu, ts, now,
NULL);
180 sched_clock_idle_wakeup_event(0);
183 static ktime_t tick_nohz_start_idle(
int cpu,
struct tick_sched *ts)
187 ts->idle_entrytime = now;
189 sched_clock_idle_sleep_event();
207 u64 get_cpu_idle_time_us(
int cpu,
u64 *last_update_time)
209 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
212 if (!tick_nohz_enabled)
216 if (last_update_time) {
217 update_ts_time_stats(cpu, ts, now, last_update_time);
218 idle = ts->idle_sleeptime;
221 ktime_t delta = ktime_sub(now, ts->idle_entrytime);
223 idle = ktime_add(ts->idle_sleeptime, delta);
225 idle = ts->idle_sleeptime;
229 return ktime_to_us(idle);
248 u64 get_cpu_iowait_time_us(
int cpu,
u64 *last_update_time)
250 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
253 if (!tick_nohz_enabled)
257 if (last_update_time) {
258 update_ts_time_stats(cpu, ts, now, last_update_time);
259 iowait = ts->iowait_sleeptime;
262 ktime_t delta = ktime_sub(now, ts->idle_entrytime);
264 iowait = ktime_add(ts->iowait_sleeptime, delta);
266 iowait = ts->iowait_sleeptime;
270 return ktime_to_us(iowait);
274 static ktime_t tick_nohz_stop_sched_tick(
struct tick_sched *ts,
277 unsigned long seq, last_jiffies, next_jiffies, delta_jiffies;
278 ktime_t last_update, expires,
ret = { .tv64 = 0 };
279 unsigned long rcu_delta_jiffies;
285 seq = read_seqbegin(&xtime_lock);
286 last_update = last_jiffies_update;
289 }
while (read_seqretry(&xtime_lock, seq));
293 next_jiffies = last_jiffies + 1;
298 delta_jiffies = next_jiffies - last_jiffies;
299 if (rcu_delta_jiffies < delta_jiffies) {
300 next_jiffies = last_jiffies + rcu_delta_jiffies;
301 delta_jiffies = rcu_delta_jiffies;
308 if (!ts->tick_stopped && delta_jiffies == 1)
312 if ((
long)delta_jiffies >= 1) {
327 if (cpu == tick_do_timer_cpu) {
328 tick_do_timer_cpu = TICK_DO_TIMER_NONE;
329 ts->do_timer_last = 1;
330 }
else if (tick_do_timer_cpu != TICK_DO_TIMER_NONE) {
332 ts->do_timer_last = 0;
333 }
else if (!ts->do_timer_last) {
362 if (ts->tick_stopped && ktime_equal(expires, dev->next_event))
374 if (!ts->tick_stopped) {
375 nohz_balance_enter_idle(cpu);
376 calc_load_enter_idle();
378 ts->last_tick = hrtimer_get_expires(&ts->sched_timer);
379 ts->tick_stopped = 1;
387 if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
392 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
396 if (hrtimer_active(&ts->sched_timer))
409 ts->next_jiffies = next_jiffies;
410 ts->last_jiffies = last_jiffies;
411 ts->sleep_length = ktime_sub(dev->next_event, now);
416 static bool can_stop_idle_tick(
int cpu,
struct tick_sched *ts)
426 if (cpu == tick_do_timer_cpu)
427 tick_do_timer_cpu = TICK_DO_TIMER_NONE;
430 if (
unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
437 static int ratelimit;
439 if (ratelimit < 10 &&
451 static void __tick_nohz_idle_enter(
struct tick_sched *ts)
456 now = tick_nohz_start_idle(cpu, ts);
458 if (can_stop_idle_tick(cpu, ts)) {
459 int was_stopped = ts->tick_stopped;
463 expires = tick_nohz_stop_sched_tick(ts, now, cpu);
466 ts->idle_expires = expires;
469 if (!was_stopped && ts->tick_stopped)
470 ts->idle_jiffies = ts->last_jiffies;
486 void tick_nohz_idle_enter(
void)
488 struct tick_sched *
ts;
498 set_cpu_sd_state_idle();
509 __tick_nohz_idle_enter(ts);
522 void tick_nohz_irq_exit(
void)
529 __tick_nohz_idle_enter(ts);
537 ktime_t tick_nohz_get_sleep_length(
void)
541 return ts->sleep_length;
544 static void tick_nohz_restart(
struct tick_sched *ts,
ktime_t now)
547 hrtimer_set_expires(&ts->sched_timer, ts->last_tick);
553 if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
554 hrtimer_start_expires(&ts->sched_timer,
557 if (hrtimer_active(&ts->sched_timer))
561 hrtimer_get_expires(&ts->sched_timer), 0))
566 tick_do_update_jiffies64(now);
570 static void tick_nohz_restart_sched_tick(
struct tick_sched *ts,
ktime_t now)
573 tick_do_update_jiffies64(now);
576 calc_load_exit_idle();
581 ts->tick_stopped = 0;
582 ts->idle_exittime = now;
584 tick_nohz_restart(ts, now);
587 static void tick_nohz_account_idle_ticks(
struct tick_sched *ts)
589 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
596 ticks =
jiffies - ts->idle_jiffies;
612 void tick_nohz_idle_exit(
void)
615 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
624 if (ts->idle_active || ts->tick_stopped)
628 tick_nohz_stop_idle(cpu, now);
630 if (ts->tick_stopped) {
631 tick_nohz_restart_sched_tick(ts, now);
632 tick_nohz_account_idle_ticks(ts);
638 static int tick_nohz_reprogram(
struct tick_sched *ts,
ktime_t now)
647 static void tick_nohz_handler(
struct clock_event_device *dev)
663 if (
unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
664 tick_do_timer_cpu =
cpu;
667 if (tick_do_timer_cpu == cpu)
668 tick_do_update_jiffies64(now);
678 if (ts->tick_stopped) {
686 while (tick_nohz_reprogram(ts, now)) {
688 tick_do_update_jiffies64(now);
695 static void tick_nohz_switch_to_nohz(
void)
700 if (!tick_nohz_enabled)
709 ts->nohz_mode = NOHZ_MODE_LOWRES;
717 next = tick_init_jiffy_update();
720 hrtimer_set_expires(&ts->sched_timer, next);
739 static void tick_nohz_kick_tick(
int cpu,
ktime_t now)
744 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
751 delta = ktime_sub(hrtimer_get_expires(&ts->sched_timer), now);
755 tick_nohz_restart(ts, now);
759 static inline void tick_check_nohz(
int cpu)
761 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
764 if (!ts->idle_active && !ts->tick_stopped)
768 tick_nohz_stop_idle(cpu, now);
769 if (ts->tick_stopped) {
770 tick_nohz_update_jiffies(now);
771 tick_nohz_kick_tick(cpu, now);
777 static inline void tick_nohz_switch_to_nohz(
void) { }
778 static inline void tick_check_nohz(
int cpu) { }
787 tick_check_oneshot_broadcast(cpu);
788 tick_check_nohz(cpu);
794 #ifdef CONFIG_HIGH_RES_TIMERS
801 struct tick_sched *ts =
815 if (
unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
816 tick_do_timer_cpu =
cpu;
820 if (tick_do_timer_cpu == cpu)
821 tick_do_update_jiffies64(now);
836 if (ts->tick_stopped) {
850 static int sched_skew_tick;
852 static int __init skew_tick(
char *str)
863 void tick_setup_sched_timer(
void)
872 ts->sched_timer.function = tick_sched_timer;
875 hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
878 if (sched_skew_tick) {
882 hrtimer_add_expires_ns(&ts->sched_timer, offset);
887 hrtimer_start_expires(&ts->sched_timer,
890 if (hrtimer_active(&ts->sched_timer))
896 if (tick_nohz_enabled)
897 ts->nohz_mode = NOHZ_MODE_HIGHRES;
902 #if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS
903 void tick_cancel_sched_timer(
int cpu)
905 struct tick_sched *ts = &
per_cpu(tick_cpu_sched, cpu);
907 # ifdef CONFIG_HIGH_RES_TIMERS
908 if (ts->sched_timer.base)
912 ts->nohz_mode = NOHZ_MODE_INACTIVE;
952 if (ts->nohz_mode != NOHZ_MODE_INACTIVE)
961 tick_nohz_switch_to_nohz();