x86: merge sched_clock handling
[safe/jmp/linux-2.6] / arch / x86 / kernel / tsc.c
1 #include <linux/sched.h>
2 #include <linux/init.h>
3 #include <linux/module.h>
4 #include <linux/timer.h>
5
6 unsigned int cpu_khz;           /* TSC clocks / usec, not used here */
7 EXPORT_SYMBOL(cpu_khz);
8 unsigned int tsc_khz;
9 EXPORT_SYMBOL(tsc_khz);
10
11 /*
12  * TSC can be unstable due to cpufreq or due to unsynced TSCs
13  */
14 int tsc_unstable;
15
16 /* native_sched_clock() is called before tsc_init(), so
17    we must start with the TSC soft disabled to prevent
18    erroneous rdtsc usage on !cpu_has_tsc processors */
19 int tsc_disabled = -1;
20
21 /*
22  * Scheduler clock - returns current time in nanosec units.
23  */
24 u64 native_sched_clock(void)
25 {
26         u64 this_offset;
27
28         /*
29          * Fall back to jiffies if there's no TSC available:
30          * ( But note that we still use it if the TSC is marked
31          *   unstable. We do this because unlike Time Of Day,
32          *   the scheduler clock tolerates small errors and it's
33          *   very important for it to be as fast as the platform
34          *   can achive it. )
35          */
36         if (unlikely(tsc_disabled)) {
37                 /* No locking but a rare wrong value is not a big deal: */
38                 return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ);
39         }
40
41         /* read the Time Stamp Counter: */
42         rdtscll(this_offset);
43
44         /* return the value in ns */
45         return cycles_2_ns(this_offset);
46 }
47
48 /* We need to define a real function for sched_clock, to override the
49    weak default version */
50 #ifdef CONFIG_PARAVIRT
51 unsigned long long sched_clock(void)
52 {
53         return paravirt_sched_clock();
54 }
55 #else
56 unsigned long long
57 sched_clock(void) __attribute__((alias("native_sched_clock")));
58 #endif
59
60 int check_tsc_unstable(void)
61 {
62         return tsc_unstable;
63 }
64 EXPORT_SYMBOL_GPL(check_tsc_unstable);
65
66 #ifdef CONFIG_X86_TSC
67 int __init notsc_setup(char *str)
68 {
69         printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
70                         "cannot disable TSC completely.\n");
71         tsc_disabled = 1;
72         return 1;
73 }
74 #else
75 /*
76  * disable flag for tsc. Takes effect by clearing the TSC cpu flag
77  * in cpu/common.c
78  */
79 int __init notsc_setup(char *str)
80 {
81         setup_clear_cpu_cap(X86_FEATURE_TSC);
82         return 1;
83 }
84 #endif
85
86 __setup("notsc", notsc_setup);