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.c24
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}
204EXPORT_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();