Merge remote-tracking branch 'linus/master' into x86/urgent
[sfrench/cifs-2.6.git] / arch / x86 / kernel / tsc.c
index 2c9cf0fd78f59a66d1c802d26a4956319f1b9c1b..a62c201c97eccf31fa90d05dec5e5cf5102ead74 100644 (file)
@@ -290,14 +290,15 @@ static inline int pit_verify_msb(unsigned char val)
 static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *deltap)
 {
        int count;
-       u64 tsc = 0;
+       u64 tsc = 0, prev_tsc = 0;
 
        for (count = 0; count < 50000; count++) {
                if (!pit_verify_msb(val))
                        break;
+               prev_tsc = tsc;
                tsc = get_cycles();
        }
-       *deltap = get_cycles() - tsc;
+       *deltap = get_cycles() - prev_tsc;
        *tscp = tsc;
 
        /*
@@ -311,9 +312,9 @@ static inline int pit_expect_msb(unsigned char val, u64 *tscp, unsigned long *de
  * How many MSB values do we want to see? We aim for
  * a maximum error rate of 500ppm (in practice the
  * real error is much smaller), but refuse to spend
- * more than 25ms on it.
+ * more than 50ms on it.
  */
-#define MAX_QUICK_PIT_MS 25
+#define MAX_QUICK_PIT_MS 50
 #define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
 
 static unsigned long quick_pit_calibrate(void)
@@ -383,15 +384,12 @@ success:
         *
         * As a result, we can depend on there not being
         * any odd delays anywhere, and the TSC reads are
-        * reliable (within the error). We also adjust the
-        * delta to the middle of the error bars, just
-        * because it looks nicer.
+        * reliable (within the error).
         *
         * kHz = ticks / time-in-seconds / 1000;
         * kHz = (t2 - t1) / (I * 256 / PIT_TICK_RATE) / 1000
         * kHz = ((t2 - t1) * PIT_TICK_RATE) / (I * 256 * 1000)
         */
-       delta += (long)(d2 - d1)/2;
        delta *= PIT_TICK_RATE;
        do_div(delta, i*256*1000);
        printk("Fast TSC calibration using PIT\n");
@@ -995,3 +993,23 @@ void __init tsc_init(void)
        check_system_tsc_reliable();
 }
 
+#ifdef CONFIG_SMP
+/*
+ * If we have a constant TSC and are using the TSC for the delay loop,
+ * we can skip clock calibration if another cpu in the same socket has already
+ * been calibrated. This assumes that CONSTANT_TSC applies to all
+ * cpus in the socket - this should be a safe assumption.
+ */
+unsigned long __cpuinit calibrate_delay_is_known(void)
+{
+       int i, cpu = smp_processor_id();
+
+       if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC))
+               return 0;
+
+       for_each_online_cpu(i)
+               if (cpu_data(i).phys_proc_id == cpu_data(cpu).phys_proc_id)
+                       return cpu_data(i).loops_per_jiffy;
+       return 0;
+}
+#endif