diff options
Diffstat (limited to 'kernel/time/clocksource.c')
-rw-r--r-- | kernel/time/clocksource.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 407c0894ef37..b65b242f04dd 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -469,6 +469,47 @@ void clocksource_touch_watchdog(void) | |||
469 | #ifdef CONFIG_GENERIC_TIME | 469 | #ifdef CONFIG_GENERIC_TIME |
470 | 470 | ||
471 | /** | 471 | /** |
472 | * clocksource_max_deferment - Returns max time the clocksource can be deferred | ||
473 | * @cs: Pointer to clocksource | ||
474 | * | ||
475 | */ | ||
476 | static u64 clocksource_max_deferment(struct clocksource *cs) | ||
477 | { | ||
478 | u64 max_nsecs, max_cycles; | ||
479 | |||
480 | /* | ||
481 | * Calculate the maximum number of cycles that we can pass to the | ||
482 | * cyc2ns function without overflowing a 64-bit signed result. The | ||
483 | * maximum number of cycles is equal to ULLONG_MAX/cs->mult which | ||
484 | * is equivalent to the below. | ||
485 | * max_cycles < (2^63)/cs->mult | ||
486 | * max_cycles < 2^(log2((2^63)/cs->mult)) | ||
487 | * max_cycles < 2^(log2(2^63) - log2(cs->mult)) | ||
488 | * max_cycles < 2^(63 - log2(cs->mult)) | ||
489 | * max_cycles < 1 << (63 - log2(cs->mult)) | ||
490 | * Please note that we add 1 to the result of the log2 to account for | ||
491 | * any rounding errors, ensure the above inequality is satisfied and | ||
492 | * no overflow will occur. | ||
493 | */ | ||
494 | max_cycles = 1ULL << (63 - (ilog2(cs->mult) + 1)); | ||
495 | |||
496 | /* | ||
497 | * The actual maximum number of cycles we can defer the clocksource is | ||
498 | * determined by the minimum of max_cycles and cs->mask. | ||
499 | */ | ||
500 | max_cycles = min_t(u64, max_cycles, (u64) cs->mask); | ||
501 | max_nsecs = clocksource_cyc2ns(max_cycles, cs->mult, cs->shift); | ||
502 | |||
503 | /* | ||
504 | * To ensure that the clocksource does not wrap whilst we are idle, | ||
505 | * limit the time the clocksource can be deferred by 12.5%. Please | ||
506 | * note a margin of 12.5% is used because this can be computed with | ||
507 | * a shift, versus say 10% which would require division. | ||
508 | */ | ||
509 | return max_nsecs - (max_nsecs >> 5); | ||
510 | } | ||
511 | |||
512 | /** | ||
472 | * clocksource_select - Select the best clocksource available | 513 | * clocksource_select - Select the best clocksource available |
473 | * | 514 | * |
474 | * Private function. Must hold clocksource_mutex when called. | 515 | * Private function. Must hold clocksource_mutex when called. |
@@ -564,6 +605,9 @@ static void clocksource_enqueue(struct clocksource *cs) | |||
564 | */ | 605 | */ |
565 | int clocksource_register(struct clocksource *cs) | 606 | int clocksource_register(struct clocksource *cs) |
566 | { | 607 | { |
608 | /* calculate max idle time permitted for this clocksource */ | ||
609 | cs->max_idle_ns = clocksource_max_deferment(cs); | ||
610 | |||
567 | mutex_lock(&clocksource_mutex); | 611 | mutex_lock(&clocksource_mutex); |
568 | clocksource_enqueue(cs); | 612 | clocksource_enqueue(cs); |
569 | clocksource_select(); | 613 | clocksource_select(); |