• Thomas Gleixner's avatar
    [x86] Fix TSC calibration issues · fbb16e24
    Thomas Gleixner authored
    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 bfc0f594
    "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: default avatarLarry Finger <Larry.Finger@lwfinger.net>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    fbb16e24
tsc.c 16.8 KB