Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ed5316d4457b35c7b4942af028d6b878174264f7
Commit:     ed5316d4457b35c7b4942af028d6b878174264f7
Parent:     9d24a81e84cee7cbf4656d178842838ac5ab23a4
Author:     Jack Steiner <[EMAIL PROTECTED]>
AuthorDate: Thu Jan 11 01:52:44 2007 +0100
Committer:  Andi Kleen <[EMAIL PROTECTED]>
CommitDate: Thu Jan 11 01:52:44 2007 +0100

    [PATCH] x86-64: - Ignore long SMI interrupts in clock calibration
    
    Ensure that no SMI interrupts occur between the read of the HPET & TSC
    in the clock calibration loop.
    
    I noticed that a 2.66GHz system incorrectly detected the processor
    clock speed about 1/7 of the time:
    
        time.c: Detected 2660.005 MHz processor.        (most of the time)
        time.c: Detected 2988.203 MHz processor.        (sometime)
    
    The problem is caused by an SMI interrupt occuring in hpet_calibrate_tsc()
    between the read of the HPET & TSC. Prior to switching the BIOS into
    ACPI mode, it appears that every 27msec an SMI interrupt occurs. The
    SMI interrupt takes 4.8 msec to process.
    
    Note: On my test system, TICK_MIN had to be >380. I picked 5000
    to minimize risk of having a value that is too small for other
    platforms.
    
    Signed-off-by: Jack Steiner <[EMAIL PROTECTED]>
    Signed-off-by: Andi Kleen <[EMAIL PROTECTED]>
    
     arch/x86_64/kernel/time.c |   25 +++++++++++++++++++++----
     1 file changed, 21 insertions(+), 4 deletions(-)
---
 arch/x86_64/kernel/time.c |   25 +++++++++++++++++++++----
 1 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 9f05bc9..5cc76d0 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -656,6 +656,25 @@ core_initcall(cpufreq_tsc);
  */
 
 #define TICK_COUNT 100000000
+#define TICK_MIN   5000
+
+/*
+ * Some platforms take periodic SMI interrupts with 5ms duration. Make sure 
none
+ * occurs between the reads of the hpet & TSC.
+ */
+static void __init read_hpet_tsc(int *hpet, int *tsc)
+{
+       int tsc1, tsc2, hpet1;
+
+       do {
+               tsc1 = get_cycles_sync();
+               hpet1 = hpet_readl(HPET_COUNTER);
+               tsc2 = get_cycles_sync();
+       } while (tsc2 - tsc1 > TICK_MIN);
+       *hpet = hpet1;
+       *tsc = tsc2;
+}
+
 
 static unsigned int __init hpet_calibrate_tsc(void)
 {
@@ -666,13 +685,11 @@ static unsigned int __init hpet_calibrate_tsc(void)
        local_irq_save(flags);
        local_irq_disable();
 
-       hpet_start = hpet_readl(HPET_COUNTER);
-       rdtscl(tsc_start);
+       read_hpet_tsc(&hpet_start, &tsc_start);
 
        do {
                local_irq_disable();
-               hpet_now = hpet_readl(HPET_COUNTER);
-               tsc_now = get_cycles_sync();
+               read_hpet_tsc(&hpet_now, &tsc_now);
                local_irq_restore(flags);
        } while ((tsc_now - tsc_start) < TICK_COUNT &&
                 (hpet_now - hpet_start) < TICK_COUNT);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to