diff options
-rw-r--r-- | kernel/time/clocksource.c | 26 | ||||
-rw-r--r-- | kernel/time/sched_clock.c | 4 |
2 files changed, 14 insertions, 16 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 2148f413256c..ace95763b3a6 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -469,6 +469,9 @@ static u32 clocksource_max_adjustment(struct clocksource *cs) | |||
469 | * @shift: cycle to nanosecond divisor (power of two) | 469 | * @shift: cycle to nanosecond divisor (power of two) |
470 | * @maxadj: maximum adjustment value to mult (~11%) | 470 | * @maxadj: maximum adjustment value to mult (~11%) |
471 | * @mask: bitmask for two's complement subtraction of non 64 bit counters | 471 | * @mask: bitmask for two's complement subtraction of non 64 bit counters |
472 | * | ||
473 | * NOTE: This function includes a safety margin of 50%, so that bad clock values | ||
474 | * can be detected. | ||
472 | */ | 475 | */ |
473 | u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask) | 476 | u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask) |
474 | { | 477 | { |
@@ -490,11 +493,14 @@ u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask) | |||
490 | max_cycles = min(max_cycles, mask); | 493 | max_cycles = min(max_cycles, mask); |
491 | max_nsecs = clocksource_cyc2ns(max_cycles, mult - maxadj, shift); | 494 | max_nsecs = clocksource_cyc2ns(max_cycles, mult - maxadj, shift); |
492 | 495 | ||
496 | /* Return 50% of the actual maximum, so we can detect bad values */ | ||
497 | max_nsecs >>= 1; | ||
498 | |||
493 | return max_nsecs; | 499 | return max_nsecs; |
494 | } | 500 | } |
495 | 501 | ||
496 | /** | 502 | /** |
497 | * clocksource_max_deferment - Returns max time the clocksource can be deferred | 503 | * clocksource_max_deferment - Returns max time the clocksource should be deferred |
498 | * @cs: Pointer to clocksource | 504 | * @cs: Pointer to clocksource |
499 | * | 505 | * |
500 | */ | 506 | */ |
@@ -504,13 +510,7 @@ static u64 clocksource_max_deferment(struct clocksource *cs) | |||
504 | 510 | ||
505 | max_nsecs = clocks_calc_max_nsecs(cs->mult, cs->shift, cs->maxadj, | 511 | max_nsecs = clocks_calc_max_nsecs(cs->mult, cs->shift, cs->maxadj, |
506 | cs->mask); | 512 | cs->mask); |
507 | /* | 513 | return max_nsecs; |
508 | * To ensure that the clocksource does not wrap whilst we are idle, | ||
509 | * limit the time the clocksource can be deferred by 12.5%. Please | ||
510 | * note a margin of 12.5% is used because this can be computed with | ||
511 | * a shift, versus say 10% which would require division. | ||
512 | */ | ||
513 | return max_nsecs - (max_nsecs >> 3); | ||
514 | } | 514 | } |
515 | 515 | ||
516 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET | 516 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET |
@@ -659,10 +659,9 @@ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq) | |||
659 | * conversion precision. 10 minutes is still a reasonable | 659 | * conversion precision. 10 minutes is still a reasonable |
660 | * amount. That results in a shift value of 24 for a | 660 | * amount. That results in a shift value of 24 for a |
661 | * clocksource with mask >= 40bit and f >= 4GHz. That maps to | 661 | * clocksource with mask >= 40bit and f >= 4GHz. That maps to |
662 | * ~ 0.06ppm granularity for NTP. We apply the same 12.5% | 662 | * ~ 0.06ppm granularity for NTP. |
663 | * margin as we do in clocksource_max_deferment() | ||
664 | */ | 663 | */ |
665 | sec = (cs->mask - (cs->mask >> 3)); | 664 | sec = cs->mask; |
666 | do_div(sec, freq); | 665 | do_div(sec, freq); |
667 | do_div(sec, scale); | 666 | do_div(sec, scale); |
668 | if (!sec) | 667 | if (!sec) |
@@ -674,9 +673,8 @@ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq) | |||
674 | NSEC_PER_SEC / scale, sec * scale); | 673 | NSEC_PER_SEC / scale, sec * scale); |
675 | 674 | ||
676 | /* | 675 | /* |
677 | * for clocksources that have large mults, to avoid overflow. | 676 | * Ensure clocksources that have large 'mult' values don't overflow |
678 | * Since mult may be adjusted by ntp, add an safety extra margin | 677 | * when adjusted. |
679 | * | ||
680 | */ | 678 | */ |
681 | cs->maxadj = clocksource_max_adjustment(cs); | 679 | cs->maxadj = clocksource_max_adjustment(cs); |
682 | while ((cs->mult + cs->maxadj < cs->mult) | 680 | while ((cs->mult + cs->maxadj < cs->mult) |
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c index 01d2d15aa662..3b8ae45020c1 100644 --- a/kernel/time/sched_clock.c +++ b/kernel/time/sched_clock.c | |||
@@ -125,9 +125,9 @@ void __init sched_clock_register(u64 (*read)(void), int bits, | |||
125 | 125 | ||
126 | new_mask = CLOCKSOURCE_MASK(bits); | 126 | new_mask = CLOCKSOURCE_MASK(bits); |
127 | 127 | ||
128 | /* calculate how many ns until we wrap */ | 128 | /* calculate how many nanosecs until we risk wrapping */ |
129 | wrap = clocks_calc_max_nsecs(new_mult, new_shift, 0, new_mask); | 129 | wrap = clocks_calc_max_nsecs(new_mult, new_shift, 0, new_mask); |
130 | new_wrap_kt = ns_to_ktime(wrap - (wrap >> 3)); | 130 | new_wrap_kt = ns_to_ktime(wrap); |
131 | 131 | ||
132 | /* update epoch for new counter and update epoch_ns from old counter*/ | 132 | /* update epoch for new counter and update epoch_ns from old counter*/ |
133 | new_epoch = read(); | 133 | new_epoch = read(); |