linux/arch/x86
Linus Torvalds 68f30fbee1 x86, tsc: Fix SMI induced variation in quick_pit_calibrate()
pit_expect_msb() returns success wrongly in the below SMI scenario:

a. pit_verify_msb() has not yet seen the MSB transition.

b. we are close to the MSB transition though and got a SMI immediately after
   returning from pit_verify_msb() which didn't see the MSB transition. PIT MSB
   transition has happened somewhere during SMI execution.

c. returned from SMI and we noted down the 'tsc', saw the pit MSB change now and
   exited the loop to calculate 'deltatsc'. Instead of noting the TSC at the MSB
   transition, we are way off because of the SMI.  And as the SMI happened
   between the pit_verify_msb() and before the 'tsc' is recorded in the
   for loop, 'delattsc' (d1/d2 in quick_pit_calibrate()) will be small and
   quick_pit_calibrate() will not notice this error.

Depending on whether SMI disturbance happens while computing d1 or d2, we will
see the TSC calibrated value smaller or bigger than the expected value. As a
result, in a cluster we were seeing a variation of approximately +/- 20MHz in
the calibrated values, resulting in NTP failures.

  [ As far as the SMI source is concerned, this is a periodic SMI that gets
    disabled after ACPI is enabled by the OS. But the TSC calibration happens
    before the ACPI is enabled. ]

To address this, change pit_expect_msb() so that

 - the 'tsc' is the TSC in between the two reads that read the MSB
change from the PIT (same as before)

 - the 'delta' is the difference in TSC from *before* the MSB changed
to *after* the MSB changed.

Now the delta is twice as big as before (it covers four PIT accesses,
roughly 4us) and quick_pit_calibrate() will loop a bit longer to get
the calibrated value with in the 500ppm precision. As the delta (d1/d2)
covers four PIT accesses, actual calibrated result might be closer to
250ppm precision.

As the loop now takes longer to stabilize, double MAX_QUICK_PIT_MS to 50.

SMI disturbance will showup as much larger delta's and the loop will take
longer than usual for the result to be with in the accepted precision. Or will
fallback to slow PIT calibration if it takes more than 50msec.

Also while we are at this, remove the calibration correction that aims to
get the result to the middle of the error bars. We really don't know which
direction to correct into, so remove it.

Reported-and-tested-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Link: http://lkml.kernel.org/r/1326843337.5291.4.camel@sbsiddha-mobl2
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2012-01-17 15:46:51 -08:00
..
boot doc: fix broken references 2011-09-27 18:08:04 +02:00
configs iommu: Rename the DMAR and INTR_REMAP config options 2011-09-21 10:22:03 +02:00
crypto Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux 2011-11-06 19:44:47 -08:00
ia32 x86-64: Cleanup some assembly entry points 2011-12-05 17:24:43 +01:00
include/asm x86/UV2: Add accounting for BAU strong nacks 2012-01-17 09:09:59 +01:00
kernel x86, tsc: Fix SMI induced variation in quick_pit_calibrate() 2012-01-17 15:46:51 -08:00
kvm KVM: Don't automatically expose the TSC deadline timer in cpuid 2011-12-26 13:27:44 +02:00
lguest lguest: add export.h to lguest files for THIS_MODULE/EXPORT_SYMBOL 2011-10-31 19:32:13 -04:00
lib x86, opcode: ANDN and Group 17 in x86-opcode-map.txt 2012-01-17 12:11:54 -08:00
math-emu
mm Merge branch 'x86-cleanups-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2012-01-06 14:00:12 -08:00
net net: bpf_jit: fix an off-one bug in x86_64 cond jump target 2011-12-19 15:47:29 -05:00
oprofile Merge branch 'core' of git://amd64.org/linux/rric into perf/core 2011-11-15 11:05:18 +01:00
pci x86: Fix files explicitly requiring export.h for EXPORT_SYMBOL/THIS_MODULE 2011-10-31 19:30:35 -04:00
platform x86/UV2: Add accounting for BAU strong nacks 2012-01-17 09:09:59 +01:00
power x86: Fix files explicitly requiring export.h for EXPORT_SYMBOL/THIS_MODULE 2011-10-31 19:30:35 -04:00
tools x86/tools: Add decoded instruction dump mode 2011-12-05 14:53:23 +01:00
um fix braino in um patchset (mea culpa) 2011-11-21 12:10:21 -08:00
vdso Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2011-10-28 05:03:12 -07:00
video x86: fix up files really needing to include module.h 2011-10-31 19:30:36 -04:00
xen Merge branch 'memblock-kill-early_node_map' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc into core/memblock 2011-12-20 12:14:26 +01:00
.gitignore
Kbuild net: filter: Just In Time compiler for x86-64 2011-04-27 23:05:08 -07:00
Kconfig x86/kconfig: Move the ZONE_DMA entry under a menu 2012-01-17 10:41:36 +01:00
Kconfig.cpu x86: Add support for cmpxchg_double 2011-06-25 12:17:32 -07:00
Kconfig.debug doc: fix broken references 2011-09-27 18:08:04 +02:00
Makefile Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2010-10-21 13:06:00 -07:00
Makefile_32.cpu x86, cpu: Move AMD Elan Kconfig under "Processor family" 2011-04-08 13:01:25 -07:00
Makefile.um um: take arch/um/sys-x86 to arch/x86/um 2011-11-02 14:15:05 +01:00