diff options
Diffstat (limited to 'arch/x86/kernel/tsc.c')
| -rw-r--r-- | arch/x86/kernel/tsc.c | 28 | 
1 files changed, 24 insertions, 4 deletions
| diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 2e076a459a0c..a698196377be 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -1180,6 +1180,12 @@ void mark_tsc_unstable(char *reason)  EXPORT_SYMBOL_GPL(mark_tsc_unstable); +static void __init tsc_disable_clocksource_watchdog(void) +{ +	clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY; +	clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; +} +  static void __init check_system_tsc_reliable(void)  {  #if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC) @@ -1196,6 +1202,23 @@ static void __init check_system_tsc_reliable(void)  #endif  	if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))  		tsc_clocksource_reliable = 1; + +	/* +	 * Disable the clocksource watchdog when the system has: +	 *  - TSC running at constant frequency +	 *  - TSC which does not stop in C-States +	 *  - the TSC_ADJUST register which allows to detect even minimal +	 *    modifications +	 *  - not more than two sockets. As the number of sockets cannot be +	 *    evaluated at the early boot stage where this has to be +	 *    invoked, check the number of online memory nodes as a +	 *    fallback solution which is an reasonable estimate. +	 */ +	if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && +	    boot_cpu_has(X86_FEATURE_NONSTOP_TSC) && +	    boot_cpu_has(X86_FEATURE_TSC_ADJUST) && +	    nr_online_nodes <= 2) +		tsc_disable_clocksource_watchdog();  }  /* @@ -1387,9 +1410,6 @@ static int __init init_tsc_clocksource(void)  	if (tsc_unstable)  		goto unreg; -	if (tsc_clocksource_reliable || no_tsc_watchdog) -		clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -  	if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3))  		clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; @@ -1527,7 +1547,7 @@ void __init tsc_init(void)  	}  	if (tsc_clocksource_reliable || no_tsc_watchdog) -		clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY; +		tsc_disable_clocksource_watchdog();  	clocksource_register_khz(&clocksource_tsc_early, tsc_khz);  	detect_art(); |