Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[cascardo/linux.git] / include / asm-i386 / tsc.h
index 97b828c..3f3c1fa 100644 (file)
@@ -6,22 +6,10 @@
 #ifndef _ASM_i386_TSC_H
 #define _ASM_i386_TSC_H
 
-#include <linux/config.h>
 #include <asm/processor.h>
 
 /*
- * Standard way to access the cycle counter on i586+ CPUs.
- * Currently only used on SMP.
- *
- * If you really have a SMP machine with i486 chips or older,
- * compile for that, and this will just always return zero.
- * That's ok, it just means that the nicer scheduling heuristics
- * won't work for you.
- *
- * We only use the low 32 bits, and we'd simply better make sure
- * that we reschedule before that wraps. Scheduling at least every
- * four billion cycles just basically sounds like a good idea,
- * regardless of how fast the machine is.
+ * Standard way to access the cycle counter.
  */
 typedef unsigned long long cycles_t;
 
@@ -43,7 +31,42 @@ static inline cycles_t get_cycles(void)
        return ret;
 }
 
+/* Like get_cycles, but make sure the CPU is synchronized. */
+static __always_inline cycles_t get_cycles_sync(void)
+{
+       unsigned long long ret;
+       unsigned eax;
+
+       /*
+        * Use RDTSCP if possible; it is guaranteed to be synchronous
+        * and doesn't cause a VMEXIT on Hypervisors
+        */
+       alternative_io(ASM_NOP3, ".byte 0x0f,0x01,0xf9", X86_FEATURE_RDTSCP,
+                                "=A" (ret), "0" (0ULL) : "ecx", "memory");
+       if (ret)
+               return ret;
+
+       /*
+        * Don't do an additional sync on CPUs where we know
+        * RDTSC is already synchronous:
+        */
+       alternative_io("cpuid", ASM_NOP2, X86_FEATURE_SYNC_RDTSC,
+                         "=a" (eax), "0" (1) : "ebx","ecx","edx","memory");
+       rdtscll(ret);
+
+       return ret;
+}
+
 extern void tsc_init(void);
-extern void mark_tsc_unstable(void);
+extern void mark_tsc_unstable(char *reason);
+extern int unsynchronized_tsc(void);
+extern void init_tsc_clocksource(void);
+
+/*
+ * Boot-time check whether the TSCs are synchronized across
+ * all CPUs/cores:
+ */
+extern void check_tsc_sync_source(int cpu);
+extern void check_tsc_sync_target(void);
 
 #endif