diff options
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r-- | kernel/time/tick-sched.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index a87b0468568b..a4d219398167 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/profile.h> | 20 | #include <linux/profile.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/tick.h> | 22 | #include <linux/tick.h> |
23 | #include <linux/module.h> | ||
23 | 24 | ||
24 | #include <asm/irq_regs.h> | 25 | #include <asm/irq_regs.h> |
25 | 26 | ||
@@ -75,6 +76,9 @@ static void tick_do_update_jiffies64(ktime_t now) | |||
75 | incr * ticks); | 76 | incr * ticks); |
76 | } | 77 | } |
77 | do_timer(++ticks); | 78 | do_timer(++ticks); |
79 | |||
80 | /* Keep the tick_next_period variable up to date */ | ||
81 | tick_next_period = ktime_add(last_jiffies_update, tick_period); | ||
78 | } | 82 | } |
79 | write_sequnlock(&xtime_lock); | 83 | write_sequnlock(&xtime_lock); |
80 | } | 84 | } |
@@ -187,9 +191,17 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time) | |||
187 | { | 191 | { |
188 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 192 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
189 | 193 | ||
190 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | 194 | if (!tick_nohz_enabled) |
195 | return -1; | ||
196 | |||
197 | if (ts->idle_active) | ||
198 | *last_update_time = ktime_to_us(ts->idle_lastupdate); | ||
199 | else | ||
200 | *last_update_time = ktime_to_us(ktime_get()); | ||
201 | |||
191 | return ktime_to_us(ts->idle_sleeptime); | 202 | return ktime_to_us(ts->idle_sleeptime); |
192 | } | 203 | } |
204 | EXPORT_SYMBOL_GPL(get_cpu_idle_time_us); | ||
193 | 205 | ||
194 | /** | 206 | /** |
195 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task | 207 | * tick_nohz_stop_sched_tick - stop the idle tick from the idle task |
@@ -221,7 +233,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
221 | */ | 233 | */ |
222 | if (unlikely(!cpu_online(cpu))) { | 234 | if (unlikely(!cpu_online(cpu))) { |
223 | if (cpu == tick_do_timer_cpu) | 235 | if (cpu == tick_do_timer_cpu) |
224 | tick_do_timer_cpu = -1; | 236 | tick_do_timer_cpu = TICK_DO_TIMER_NONE; |
225 | } | 237 | } |
226 | 238 | ||
227 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) | 239 | if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) |
@@ -303,7 +315,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
303 | * invoked. | 315 | * invoked. |
304 | */ | 316 | */ |
305 | if (cpu == tick_do_timer_cpu) | 317 | if (cpu == tick_do_timer_cpu) |
306 | tick_do_timer_cpu = -1; | 318 | tick_do_timer_cpu = TICK_DO_TIMER_NONE; |
307 | 319 | ||
308 | ts->idle_sleeps++; | 320 | ts->idle_sleeps++; |
309 | 321 | ||
@@ -468,7 +480,7 @@ static void tick_nohz_handler(struct clock_event_device *dev) | |||
468 | * this duty, then the jiffies update is still serialized by | 480 | * this duty, then the jiffies update is still serialized by |
469 | * xtime_lock. | 481 | * xtime_lock. |
470 | */ | 482 | */ |
471 | if (unlikely(tick_do_timer_cpu == -1)) | 483 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) |
472 | tick_do_timer_cpu = cpu; | 484 | tick_do_timer_cpu = cpu; |
473 | 485 | ||
474 | /* Check, if the jiffies need an update */ | 486 | /* Check, if the jiffies need an update */ |
@@ -570,7 +582,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
570 | * this duty, then the jiffies update is still serialized by | 582 | * this duty, then the jiffies update is still serialized by |
571 | * xtime_lock. | 583 | * xtime_lock. |
572 | */ | 584 | */ |
573 | if (unlikely(tick_do_timer_cpu == -1)) | 585 | if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) |
574 | tick_do_timer_cpu = cpu; | 586 | tick_do_timer_cpu = cpu; |
575 | #endif | 587 | #endif |
576 | 588 | ||
@@ -622,7 +634,7 @@ void tick_setup_sched_timer(void) | |||
622 | */ | 634 | */ |
623 | hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | 635 | hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); |
624 | ts->sched_timer.function = tick_sched_timer; | 636 | ts->sched_timer.function = tick_sched_timer; |
625 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ; | 637 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; |
626 | 638 | ||
627 | /* Get the next period (per cpu) */ | 639 | /* Get the next period (per cpu) */ |
628 | ts->sched_timer.expires = tick_init_jiffy_update(); | 640 | ts->sched_timer.expires = tick_init_jiffy_update(); |