diff options
Diffstat (limited to 'arch/i386/kernel/tsc.c')
-rw-r--r-- | arch/i386/kernel/tsc.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 2cfc7b09b925..46f752a8bbf3 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c | |||
@@ -23,6 +23,7 @@ | |||
23 | * an extra value to store the TSC freq | 23 | * an extra value to store the TSC freq |
24 | */ | 24 | */ |
25 | unsigned int tsc_khz; | 25 | unsigned int tsc_khz; |
26 | unsigned long long (*custom_sched_clock)(void); | ||
26 | 27 | ||
27 | int tsc_disable; | 28 | int tsc_disable; |
28 | 29 | ||
@@ -107,14 +108,14 @@ unsigned long long sched_clock(void) | |||
107 | { | 108 | { |
108 | unsigned long long this_offset; | 109 | unsigned long long this_offset; |
109 | 110 | ||
111 | if (unlikely(custom_sched_clock)) | ||
112 | return (*custom_sched_clock)(); | ||
113 | |||
110 | /* | 114 | /* |
111 | * in the NUMA case we dont use the TSC as they are not | 115 | * Fall back to jiffies if there's no TSC available: |
112 | * synchronized across all CPUs. | ||
113 | */ | 116 | */ |
114 | #ifndef CONFIG_NUMA | 117 | if (unlikely(tsc_disable)) |
115 | if (!cpu_khz || check_tsc_unstable()) | 118 | /* No locking but a rare wrong value is not a big deal: */ |
116 | #endif | ||
117 | /* no locking but a rare wrong value is not a big deal */ | ||
118 | return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); | 119 | return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); |
119 | 120 | ||
120 | /* read the Time Stamp Counter: */ | 121 | /* read the Time Stamp Counter: */ |
@@ -194,13 +195,13 @@ EXPORT_SYMBOL(recalibrate_cpu_khz); | |||
194 | void __init tsc_init(void) | 195 | void __init tsc_init(void) |
195 | { | 196 | { |
196 | if (!cpu_has_tsc || tsc_disable) | 197 | if (!cpu_has_tsc || tsc_disable) |
197 | return; | 198 | goto out_no_tsc; |
198 | 199 | ||
199 | cpu_khz = calculate_cpu_khz(); | 200 | cpu_khz = calculate_cpu_khz(); |
200 | tsc_khz = cpu_khz; | 201 | tsc_khz = cpu_khz; |
201 | 202 | ||
202 | if (!cpu_khz) | 203 | if (!cpu_khz) |
203 | return; | 204 | goto out_no_tsc; |
204 | 205 | ||
205 | printk("Detected %lu.%03lu MHz processor.\n", | 206 | printk("Detected %lu.%03lu MHz processor.\n", |
206 | (unsigned long)cpu_khz / 1000, | 207 | (unsigned long)cpu_khz / 1000, |
@@ -208,6 +209,15 @@ void __init tsc_init(void) | |||
208 | 209 | ||
209 | set_cyc2ns_scale(cpu_khz); | 210 | set_cyc2ns_scale(cpu_khz); |
210 | use_tsc_delay(); | 211 | use_tsc_delay(); |
212 | return; | ||
213 | |||
214 | out_no_tsc: | ||
215 | /* | ||
216 | * Set the tsc_disable flag if there's no TSC support, this | ||
217 | * makes it a fast flag for the kernel to see whether it | ||
218 | * should be using the TSC. | ||
219 | */ | ||
220 | tsc_disable = 1; | ||
211 | } | 221 | } |
212 | 222 | ||
213 | #ifdef CONFIG_CPU_FREQ | 223 | #ifdef CONFIG_CPU_FREQ |