linux/arch/x86
Thomas Gleixner fbb16e2438 [x86] Fix TSC calibration issues
Larry Finger reported at http://lkml.org/lkml/2008/9/1/90:
An ancient laptop of mine started throwing errors from b43legacy when
I started using 2.6.27 on it. This has been bisected to commit bfc0f59
"x86: merge tsc calibration".

The unification of the TSC code adopted mostly the 64bit code, which
prefers PMTIMER/HPET over the PIT calibration.

Larrys system has an AMD K6 CPU. Such systems are known to have
PMTIMER incarnations which run at double speed. This results in a
miscalibration of the TSC by factor 0.5. So the resulting calibrated
CPU/TSC speed is half of the real CPU speed, which means that the TSC
based delay loop will run half the time it should run. That might
explain why the b43legacy driver went berserk.

On the other hand we know about systems, where the PIT based
calibration results in random crap due to heavy SMI/SMM
disturbance. On those systems the PMTIMER/HPET based calibration logic
with SMI detection shows better results.

According to Alok also virtualized systems suffer from the PIT
calibration method.

The solution is to use a more wreckage aware aproach than the current
either/or decision.

1) reimplement the retry loop which was dropped from the 32bit code
during the merge. It repeats the calibration and selects the lowest
frequency value as this is probably the closest estimate to the real
frequency

2) Monitor the delta of the TSC values in the delay loop which waits
for the PIT counter to reach zero. If the maximum value is
significantly different from the minimum, then we have a pretty safe
indicator that the loop was disturbed by an SMI.

3) keep the pmtimer/hpet reference as a backup solution for systems
where the SMI disturbance is a permanent point of failure for PIT
based calibration

4) do the loop iteration for both methods, record the lowest value and
decide after all iterations finished.

5) Set a clear preference to PIT based calibration when the result
makes sense.

The implementation does the reference calibration based on
HPET/PMTIMER around the delay, which is necessary for the PIT anyway,
but keeps separate TSC values to ensure the "independency" of the
resulting calibration values.

Tested on various 32bit/64bit machines including Geode 266Mhz, AMD K6
(affected machine with a double speed pmtimer which I grabbed out of
the dump), Pentium class machines and AMD/Intel 64 bit boxen.

Bisected-by:  Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-09-02 20:35:56 -07:00
..
boot x86: fix build warnings in real mode code 2008-08-18 09:20:14 +02:00
configs x86: update defconfigs 2008-08-27 08:14:17 +02:00
crypto [CRYPTO] aes-x86-32: Remove unused return code 2008-04-21 10:19:21 +08:00
ia32 tracehook: exec 2008-07-26 12:00:08 -07:00
kernel [x86] Fix TSC calibration issues 2008-09-02 20:35:56 -07:00
kvm KVM: MMU: Fix torn shadow pte 2008-08-25 17:24:27 +03:00
lguest lguest: set max_pfn_mapped, growl loudly at Yinghai Lu 2008-07-29 09:58:31 +10:00
lib x86: msr: propagate errors from smp_call_function_single() 2008-08-25 17:45:48 -07:00
mach-default x86: add ->pre_time_init to x86_quirks 2008-07-20 09:25:52 +02:00
mach-es7000 x86: move the last Dprintk instance to pr_debug() 2008-07-21 21:58:34 +02:00
mach-generic x86: make generic arch support NUMAQ, fix 2008-07-08 10:35:45 +02:00
mach-rdc321x removed unused #include <linux/version.h>'s 2008-08-23 12:14:12 -07:00
mach-voyager Merge branch 'generic-ipi' into generic-ipi-for-linus 2008-07-15 21:55:59 +02:00
math-emu x86: coding style fixes to arch/x86/math-emu/reg_constant 2008-06-18 15:00:13 +02:00
mm x86: fix two modpost warnings in mm/init_64.c 2008-08-22 07:51:54 +02:00
oprofile x86: fix oprofile + hibernation badness 2008-08-20 16:18:31 +02:00
pci Un-break printk strings in x86 PCI probing code 2008-09-02 10:38:28 -07:00
power x86: fix i486 suspend to disk CR4 oops 2008-08-18 08:50:19 +02:00
vdso Merge branches 'x86/urgent', 'x86/amd-iommu', 'x86/apic', 'x86/cleanups', 'x86/core', 'x86/cpu', 'x86/fixmap', 'x86/gart', 'x86/kprobes', 'x86/memtest', 'x86/modules', 'x86/nmi', 'x86/pat', 'x86/reboot', 'x86/setup', 'x86/step', 'x86/unify-pci', 'x86/uv', 'x86/xen' and 'xen-64bit' into x86/for-linus 2008-07-21 16:37:17 +02:00
video x86: video/fbdev.c: add MODULE_LICENSE 2008-05-04 20:04:46 +02:00
xen xen: don't use sysret for sysexit32 2008-07-24 12:28:12 +02:00
Kconfig [x86] Clean up MAXSMP Kconfig, and limit NR_CPUS to 512 2008-08-25 14:15:38 -07:00
Kconfig.cpu x86: fix crash due to missing debugctlmsr on AMD K6-3 2008-07-22 14:16:37 +02:00
Kconfig.debug x86: Fix help message for STRICT_DEVMEM config option 2008-07-21 13:04:08 -07:00
Makefile x86, RDC321x: add to mach-default 2008-07-26 13:51:46 +02:00
Makefile_32.cpu x86: move i386 and x86_64 Makefiles to arch/x86 2007-10-25 22:27:34 +02:00