diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/clocksource.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index c9583382141a..dda5c7130d93 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -553,6 +553,26 @@ static u64 clocksource_max_deferment(struct clocksource *cs) | |||
553 | 553 | ||
554 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET | 554 | #ifndef CONFIG_ARCH_USES_GETTIMEOFFSET |
555 | 555 | ||
556 | static struct clocksource *clocksource_find_best(bool oneshot) | ||
557 | { | ||
558 | struct clocksource *cs; | ||
559 | |||
560 | if (!finished_booting || list_empty(&clocksource_list)) | ||
561 | return NULL; | ||
562 | |||
563 | /* | ||
564 | * We pick the clocksource with the highest rating. If oneshot | ||
565 | * mode is active, we pick the highres valid clocksource with | ||
566 | * the best rating. | ||
567 | */ | ||
568 | list_for_each_entry(cs, &clocksource_list, list) { | ||
569 | if (oneshot && !(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES)) | ||
570 | continue; | ||
571 | return cs; | ||
572 | } | ||
573 | return NULL; | ||
574 | } | ||
575 | |||
556 | /** | 576 | /** |
557 | * clocksource_select - Select the best clocksource available | 577 | * clocksource_select - Select the best clocksource available |
558 | * | 578 | * |
@@ -563,12 +583,14 @@ static u64 clocksource_max_deferment(struct clocksource *cs) | |||
563 | */ | 583 | */ |
564 | static void clocksource_select(void) | 584 | static void clocksource_select(void) |
565 | { | 585 | { |
586 | bool oneshot = tick_oneshot_mode_active(); | ||
566 | struct clocksource *best, *cs; | 587 | struct clocksource *best, *cs; |
567 | 588 | ||
568 | if (!finished_booting || list_empty(&clocksource_list)) | 589 | /* Find the best suitable clocksource */ |
590 | best = clocksource_find_best(oneshot); | ||
591 | if (!best) | ||
569 | return; | 592 | return; |
570 | /* First clocksource on the list has the best rating. */ | 593 | |
571 | best = list_first_entry(&clocksource_list, struct clocksource, list); | ||
572 | /* Check for the override clocksource. */ | 594 | /* Check for the override clocksource. */ |
573 | list_for_each_entry(cs, &clocksource_list, list) { | 595 | list_for_each_entry(cs, &clocksource_list, list) { |
574 | if (strcmp(cs->name, override_name) != 0) | 596 | if (strcmp(cs->name, override_name) != 0) |
@@ -578,8 +600,7 @@ static void clocksource_select(void) | |||
578 | * capable clocksource if the tick code is in oneshot | 600 | * capable clocksource if the tick code is in oneshot |
579 | * mode (highres or nohz) | 601 | * mode (highres or nohz) |
580 | */ | 602 | */ |
581 | if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) && | 603 | if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) && oneshot) { |
582 | tick_oneshot_mode_active()) { | ||
583 | /* Override clocksource cannot be used. */ | 604 | /* Override clocksource cannot be used. */ |
584 | printk(KERN_WARNING "Override clocksource %s is not " | 605 | printk(KERN_WARNING "Override clocksource %s is not " |
585 | "HRT compatible. Cannot switch while in " | 606 | "HRT compatible. Cannot switch while in " |