On systems where multiple chassis are reset asynchronously there is not a constant ratio between the ART frequency and the TSC time that can be provided by the boot cpu. Provide a means to disable the ART capability by arches that have this characteristic.
Signed-off-by: Mike Travis <mike.tra...@hpe.com> --- arch/x86/include/asm/tsc.h | 1 + arch/x86/kernel/tsc.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) --- linux.orig/arch/x86/include/asm/tsc.h +++ linux/arch/x86/include/asm/tsc.h @@ -36,6 +36,7 @@ extern void mark_tsc_unstable(char *reas extern int unsynchronized_tsc(void); extern int check_tsc_unstable(void); extern void mark_tsc_multi_sync_resets(char *reason); +extern void mark_tsc_art_disabled(char *reason); extern unsigned long native_calibrate_cpu(void); extern unsigned long native_calibrate_tsc(void); extern unsigned long long native_sched_clock_from_tsc(u64 tsc); --- linux.orig/arch/x86/kernel/tsc.c +++ linux/arch/x86/kernel/tsc.c @@ -955,15 +955,25 @@ core_initcall(cpufreq_register_tsc_scali #define ART_CPUID_LEAF (0x15) #define ART_MIN_DENOMINATOR (1) - /* - * If ART is present detect the numerator:denominator to convert to TSC + * If ART is present detect the numerator:denominator to convert to TSC. + * The CPU ART capability can be disabled. */ +static bool tsc_art_disabled; + +void mark_tsc_art_disabled(char *reason) +{ + if (tsc_art_disabled) + return; + tsc_art_disabled = true; + pr_info("TSC: ART disabled due to %s\n", reason); +} + static void detect_art(void) { unsigned int unused[2]; - if (boot_cpu_data.cpuid_level < ART_CPUID_LEAF) + if (boot_cpu_data.cpuid_level < ART_CPUID_LEAF || tsc_art_disabled) return; /* Don't enable ART in a VM, non-stop TSC and TSC_ADJUST required */ --