diff options
| author | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 14:36:25 +0100 | 
|---|---|---|
| committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 14:36:25 +0100 | 
| commit | a8931ef380c92d121ae74ecfb03b2d63f72eea6f (patch) | |
| tree | 980fb6b019e11e6cb1ece55b7faff184721a8053 /arch/x86/kernel/tsc_32.c | |
| parent | 90574d0a4d4b73308ae54a2a57a4f3f1fa98e984 (diff) | |
| parent | e5a5816f7875207cb0a0a7032e39a4686c5e10a4 (diff) | |
| download | olio-linux-3.10-a8931ef380c92d121ae74ecfb03b2d63f72eea6f.tar.xz olio-linux-3.10-a8931ef380c92d121ae74ecfb03b2d63f72eea6f.zip  | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/x86/kernel/tsc_32.c')
| -rw-r--r-- | arch/x86/kernel/tsc_32.c | 23 | 
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index e4790728b22..65b70637ad9 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -14,7 +14,10 @@  #include "mach_timer.h" -static int tsc_enabled; +/* native_sched_clock() is called before tsc_init(), so +   we must start with the TSC soft disabled to prevent +   erroneous rdtsc usage on !cpu_has_tsc processors */ +static int tsc_disabled = -1;  /*   * On some systems the TSC frequency does not @@ -28,8 +31,8 @@ EXPORT_SYMBOL_GPL(tsc_khz);  static int __init tsc_setup(char *str)  {  	printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " -				"cannot disable TSC completely.\n"); -	mark_tsc_unstable("user disabled TSC"); +	       "cannot disable TSC completely.\n"); +	tsc_disabled = 1;  	return 1;  }  #else @@ -120,7 +123,7 @@ unsigned long long native_sched_clock(void)  	 *   very important for it to be as fast as the platform  	 *   can achive it. )  	 */ -	if (unlikely(!tsc_enabled && !tsc_unstable)) +	if (unlikely(tsc_disabled))  		/* No locking but a rare wrong value is not a big deal: */  		return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); @@ -322,7 +325,6 @@ void mark_tsc_unstable(char *reason)  {  	if (!tsc_unstable) {  		tsc_unstable = 1; -		tsc_enabled = 0;  		printk("Marking TSC unstable due to: %s.\n", reason);  		/* Can be called before registration */  		if (clocksource_tsc.mult) @@ -336,7 +338,7 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable);  static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d)  {  	printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", -		       d->ident); +	       d->ident);  	tsc_unstable = 1;  	return 0;  } @@ -403,7 +405,7 @@ void __init tsc_init(void)  {  	int cpu; -	if (!cpu_has_tsc) +	if (!cpu_has_tsc || tsc_disabled > 0)  		return;  	cpu_khz = calculate_cpu_khz(); @@ -414,6 +416,9 @@ void __init tsc_init(void)  		return;  	} +	/* now allow native_sched_clock() to use rdtsc */ +	tsc_disabled = 0; +  	printk("Detected %lu.%03lu MHz processor.\n",  				(unsigned long)cpu_khz / 1000,  				(unsigned long)cpu_khz % 1000); @@ -441,8 +446,6 @@ void __init tsc_init(void)  	if (check_tsc_unstable()) {  		clocksource_tsc.rating = 0;  		clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; -	} else -		tsc_enabled = 1; - +	}  	clocksource_register(&clocksource_tsc);  }  |