diff options
-rw-r--r-- | kernel/time/tick-sched.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 81409bba242..911834b33b8 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -402,7 +402,6 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now) | |||
402 | 402 | ||
403 | ts->idle_tick = hrtimer_get_expires(&ts->sched_timer); | 403 | ts->idle_tick = hrtimer_get_expires(&ts->sched_timer); |
404 | ts->tick_stopped = 1; | 404 | ts->tick_stopped = 1; |
405 | ts->idle_jiffies = last_jiffies; | ||
406 | } | 405 | } |
407 | 406 | ||
408 | ts->idle_sleeps++; | 407 | ts->idle_sleeps++; |
@@ -445,9 +444,13 @@ out: | |||
445 | static void __tick_nohz_idle_enter(struct tick_sched *ts) | 444 | static void __tick_nohz_idle_enter(struct tick_sched *ts) |
446 | { | 445 | { |
447 | ktime_t now; | 446 | ktime_t now; |
447 | int was_stopped = ts->tick_stopped; | ||
448 | 448 | ||
449 | now = tick_nohz_start_idle(smp_processor_id(), ts); | 449 | now = tick_nohz_start_idle(smp_processor_id(), ts); |
450 | tick_nohz_stop_sched_tick(ts, now); | 450 | tick_nohz_stop_sched_tick(ts, now); |
451 | |||
452 | if (!was_stopped && ts->tick_stopped) | ||
453 | ts->idle_jiffies = ts->last_jiffies; | ||
451 | } | 454 | } |
452 | 455 | ||
453 | /** | 456 | /** |
@@ -548,15 +551,25 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) | |||
548 | 551 | ||
549 | static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) | 552 | static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) |
550 | { | 553 | { |
551 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | ||
552 | unsigned long ticks; | ||
553 | #endif | ||
554 | /* Update jiffies first */ | 554 | /* Update jiffies first */ |
555 | select_nohz_load_balancer(0); | 555 | select_nohz_load_balancer(0); |
556 | tick_do_update_jiffies64(now); | 556 | tick_do_update_jiffies64(now); |
557 | update_cpu_load_nohz(); | 557 | update_cpu_load_nohz(); |
558 | 558 | ||
559 | touch_softlockup_watchdog(); | ||
560 | /* | ||
561 | * Cancel the scheduled timer and restore the tick | ||
562 | */ | ||
563 | ts->tick_stopped = 0; | ||
564 | ts->idle_exittime = now; | ||
565 | |||
566 | tick_nohz_restart(ts, now); | ||
567 | } | ||
568 | |||
569 | static void tick_nohz_account_idle_ticks(struct tick_sched *ts) | ||
570 | { | ||
559 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 571 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
572 | unsigned long ticks; | ||
560 | /* | 573 | /* |
561 | * We stopped the tick in idle. Update process times would miss the | 574 | * We stopped the tick in idle. Update process times would miss the |
562 | * time we slept as update_process_times does only a 1 tick | 575 | * time we slept as update_process_times does only a 1 tick |
@@ -569,15 +582,6 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now) | |||
569 | if (ticks && ticks < LONG_MAX) | 582 | if (ticks && ticks < LONG_MAX) |
570 | account_idle_ticks(ticks); | 583 | account_idle_ticks(ticks); |
571 | #endif | 584 | #endif |
572 | |||
573 | touch_softlockup_watchdog(); | ||
574 | /* | ||
575 | * Cancel the scheduled timer and restore the tick | ||
576 | */ | ||
577 | ts->tick_stopped = 0; | ||
578 | ts->idle_exittime = now; | ||
579 | |||
580 | tick_nohz_restart(ts, now); | ||
581 | } | 585 | } |
582 | 586 | ||
583 | /** | 587 | /** |
@@ -605,8 +609,10 @@ void tick_nohz_idle_exit(void) | |||
605 | if (ts->idle_active) | 609 | if (ts->idle_active) |
606 | tick_nohz_stop_idle(cpu, now); | 610 | tick_nohz_stop_idle(cpu, now); |
607 | 611 | ||
608 | if (ts->tick_stopped) | 612 | if (ts->tick_stopped) { |
609 | tick_nohz_restart_sched_tick(ts, now); | 613 | tick_nohz_restart_sched_tick(ts, now); |
614 | tick_nohz_account_idle_ticks(ts); | ||
615 | } | ||
610 | 616 | ||
611 | local_irq_enable(); | 617 | local_irq_enable(); |
612 | } | 618 | } |
@@ -811,7 +817,8 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) | |||
811 | */ | 817 | */ |
812 | if (ts->tick_stopped) { | 818 | if (ts->tick_stopped) { |
813 | touch_softlockup_watchdog(); | 819 | touch_softlockup_watchdog(); |
814 | ts->idle_jiffies++; | 820 | if (idle_cpu(cpu)) |
821 | ts->idle_jiffies++; | ||
815 | } | 822 | } |
816 | update_process_times(user_mode(regs)); | 823 | update_process_times(user_mode(regs)); |
817 | profile_tick(CPU_PROFILING); | 824 | profile_tick(CPU_PROFILING); |