diff options
author | Alok Kataria <akataria@vmware.com> | 2008-07-01 14:43:18 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-09 01:43:25 -0400 |
commit | 0ef95533326a7b37d16025af9edc0c18e644b346 (patch) | |
tree | 216e53f744b9bd718c4f54862032c241bf59fd73 /arch/x86/kernel/tsc.c | |
parent | 746f2eb790e75676ddc3b816ba18bac4179cc744 (diff) |
x86: merge sched_clock handling
Move the basic global variable definitions and sched_clock handling in the
common "tsc.c" file.
- Unify notsc kernel command line handling for 32 bit and 64bit.
- Functional changes for 64bit.
- "tsc_disabled" is updated if "notsc" is passed at boottime.
- Fallback to jiffies for sched_clock, incase notsc is passed on
commandline.
Signed-off-by: Alok N Kataria <akataria@vmware.com>
Signed-off-by: Dan Hecht <dhecht@vmware.com>
Cc: Dan Hecht <dhecht@vmware.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/tsc.c')
-rw-r--r-- | arch/x86/kernel/tsc.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c new file mode 100644 index 000000000000..5d0be778fadd --- /dev/null +++ b/arch/x86/kernel/tsc.c | |||
@@ -0,0 +1,86 @@ | |||
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); | ||