diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/ntp.c | 3 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 35 | ||||
-rw-r--r-- | kernel/time/timer_list.c | 8 |
3 files changed, 29 insertions, 17 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 1a20715bfd6e..8ff15e5d486b 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -142,8 +142,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer) | |||
142 | time_state = TIME_OOP; | 142 | time_state = TIME_OOP; |
143 | printk(KERN_NOTICE "Clock: " | 143 | printk(KERN_NOTICE "Clock: " |
144 | "inserting leap second 23:59:60 UTC\n"); | 144 | "inserting leap second 23:59:60 UTC\n"); |
145 | leap_timer.expires = ktime_add_ns(leap_timer.expires, | 145 | hrtimer_add_expires_ns(&leap_timer, NSEC_PER_SEC); |
146 | NSEC_PER_SEC); | ||
147 | res = HRTIMER_RESTART; | 146 | res = HRTIMER_RESTART; |
148 | break; | 147 | break; |
149 | case TIME_DEL: | 148 | case TIME_DEL: |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 0581c11fe6c6..5bbb1044f847 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -300,7 +300,7 @@ void tick_nohz_stop_sched_tick(int inidle) | |||
300 | goto out; | 300 | goto out; |
301 | } | 301 | } |
302 | 302 | ||
303 | ts->idle_tick = ts->sched_timer.expires; | 303 | ts->idle_tick = hrtimer_get_expires(&ts->sched_timer); |
304 | ts->tick_stopped = 1; | 304 | ts->tick_stopped = 1; |
305 | ts->idle_jiffies = last_jiffies; | 305 | ts->idle_jiffies = last_jiffies; |
306 | rcu_enter_nohz(); | 306 | rcu_enter_nohz(); |
@@ -380,21 +380,21 @@ ktime_t tick_nohz_get_sleep_length(void) | |||
380 | static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) | 380 | static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) |
381 | { | 381 | { |
382 | hrtimer_cancel(&ts->sched_timer); | 382 | hrtimer_cancel(&ts->sched_timer); |
383 | ts->sched_timer.expires = ts->idle_tick; | 383 | hrtimer_set_expires(&ts->sched_timer, ts->idle_tick); |
384 | 384 | ||
385 | while (1) { | 385 | while (1) { |
386 | /* Forward the time to expire in the future */ | 386 | /* Forward the time to expire in the future */ |
387 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 387 | hrtimer_forward(&ts->sched_timer, now, tick_period); |
388 | 388 | ||
389 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { | 389 | if (ts->nohz_mode == NOHZ_MODE_HIGHRES) { |
390 | hrtimer_start(&ts->sched_timer, | 390 | hrtimer_start_expires(&ts->sched_timer, |
391 | ts->sched_timer.expires, | ||
392 | HRTIMER_MODE_ABS); | 391 | HRTIMER_MODE_ABS); |
393 | /* Check, if the timer was already in the past */ | 392 | /* Check, if the timer was already in the past */ |
394 | if (hrtimer_active(&ts->sched_timer)) | 393 | if (hrtimer_active(&ts->sched_timer)) |
395 | break; | 394 | break; |
396 | } else { | 395 | } else { |
397 | if (!tick_program_event(ts->sched_timer.expires, 0)) | 396 | if (!tick_program_event( |
397 | hrtimer_get_expires(&ts->sched_timer), 0)) | ||
398 | break; | 398 | break; |
399 | } | 399 | } |
400 | /* Update jiffies and reread time */ | 400 | /* Update jiffies and reread time */ |
@@ -456,14 +456,16 @@ void tick_nohz_restart_sched_tick(void) | |||
456 | */ | 456 | */ |
457 | ts->tick_stopped = 0; | 457 | ts->tick_stopped = 0; |
458 | ts->idle_exittime = now; | 458 | ts->idle_exittime = now; |
459 | |||
459 | tick_nohz_restart(ts, now); | 460 | tick_nohz_restart(ts, now); |
461 | |||
460 | local_irq_enable(); | 462 | local_irq_enable(); |
461 | } | 463 | } |
462 | 464 | ||
463 | static int tick_nohz_reprogram(struct tick_sched *ts, ktime_t now) | 465 | static int tick_nohz_reprogram(struct tick_sched *ts, ktime_t now) |
464 | { | 466 | { |
465 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 467 | hrtimer_forward(&ts->sched_timer, now, tick_period); |
466 | return tick_program_event(ts->sched_timer.expires, 0); | 468 | return tick_program_event(hrtimer_get_expires(&ts->sched_timer), 0); |
467 | } | 469 | } |
468 | 470 | ||
469 | /* | 471 | /* |
@@ -542,7 +544,7 @@ static void tick_nohz_switch_to_nohz(void) | |||
542 | next = tick_init_jiffy_update(); | 544 | next = tick_init_jiffy_update(); |
543 | 545 | ||
544 | for (;;) { | 546 | for (;;) { |
545 | ts->sched_timer.expires = next; | 547 | hrtimer_set_expires(&ts->sched_timer, next); |
546 | if (!tick_program_event(next, 0)) | 548 | if (!tick_program_event(next, 0)) |
547 | break; | 549 | break; |
548 | next = ktime_add(next, tick_period); | 550 | next = ktime_add(next, tick_period); |
@@ -567,11 +569,21 @@ static void tick_nohz_switch_to_nohz(void) | |||
567 | static void tick_nohz_kick_tick(int cpu) | 569 | static void tick_nohz_kick_tick(int cpu) |
568 | { | 570 | { |
569 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); | 571 | struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); |
572 | ktime_t delta, now; | ||
570 | 573 | ||
571 | if (!ts->tick_stopped) | 574 | if (!ts->tick_stopped) |
572 | return; | 575 | return; |
573 | 576 | ||
574 | tick_nohz_restart(ts, ktime_get()); | 577 | /* |
578 | * Do not touch the tick device, when the next expiry is either | ||
579 | * already reached or less/equal than the tick period. | ||
580 | */ | ||
581 | now = ktime_get(); | ||
582 | delta = ktime_sub(hrtimer_get_expires(&ts->sched_timer), now); | ||
583 | if (delta.tv64 <= tick_period.tv64) | ||
584 | return; | ||
585 | |||
586 | tick_nohz_restart(ts, now); | ||
575 | } | 587 | } |
576 | 588 | ||
577 | #else | 589 | #else |
@@ -668,16 +680,15 @@ void tick_setup_sched_timer(void) | |||
668 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; | 680 | ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; |
669 | 681 | ||
670 | /* Get the next period (per cpu) */ | 682 | /* Get the next period (per cpu) */ |
671 | ts->sched_timer.expires = tick_init_jiffy_update(); | 683 | hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update()); |
672 | offset = ktime_to_ns(tick_period) >> 1; | 684 | offset = ktime_to_ns(tick_period) >> 1; |
673 | do_div(offset, num_possible_cpus()); | 685 | do_div(offset, num_possible_cpus()); |
674 | offset *= smp_processor_id(); | 686 | offset *= smp_processor_id(); |
675 | ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); | 687 | hrtimer_add_expires_ns(&ts->sched_timer, offset); |
676 | 688 | ||
677 | for (;;) { | 689 | for (;;) { |
678 | hrtimer_forward(&ts->sched_timer, now, tick_period); | 690 | hrtimer_forward(&ts->sched_timer, now, tick_period); |
679 | hrtimer_start(&ts->sched_timer, ts->sched_timer.expires, | 691 | hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS); |
680 | HRTIMER_MODE_ABS); | ||
681 | /* Check, if the timer was already in the past */ | 692 | /* Check, if the timer was already in the past */ |
682 | if (hrtimer_active(&ts->sched_timer)) | 693 | if (hrtimer_active(&ts->sched_timer)) |
683 | break; | 694 | break; |
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c index f6426911e35a..a999b92a1277 100644 --- a/kernel/time/timer_list.c +++ b/kernel/time/timer_list.c | |||
@@ -66,9 +66,11 @@ print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer, | |||
66 | SEQ_printf(m, ", %s/%d", tmp, timer->start_pid); | 66 | SEQ_printf(m, ", %s/%d", tmp, timer->start_pid); |
67 | #endif | 67 | #endif |
68 | SEQ_printf(m, "\n"); | 68 | SEQ_printf(m, "\n"); |
69 | SEQ_printf(m, " # expires at %Lu nsecs [in %Ld nsecs]\n", | 69 | SEQ_printf(m, " # expires at %Lu-%Lu nsecs [in %Ld to %Ld nsecs]\n", |
70 | (unsigned long long)ktime_to_ns(timer->expires), | 70 | (unsigned long long)ktime_to_ns(hrtimer_get_softexpires(timer)), |
71 | (long long)(ktime_to_ns(timer->expires) - now)); | 71 | (unsigned long long)ktime_to_ns(hrtimer_get_expires(timer)), |
72 | (long long)(ktime_to_ns(hrtimer_get_softexpires(timer)) - now), | ||
73 | (long long)(ktime_to_ns(hrtimer_get_expires(timer)) - now)); | ||
72 | } | 74 | } |
73 | 75 | ||
74 | static void | 76 | static void |