diff options
Diffstat (limited to 'arch/x86/kernel/tsc_64.c')
-rw-r--r-- | arch/x86/kernel/tsc_64.c | 27 |
1 files changed, 4 insertions, 23 deletions
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c index 01fc9f0c39e2..d3bebaaad842 100644 --- a/arch/x86/kernel/tsc_64.c +++ b/arch/x86/kernel/tsc_64.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <asm/hpet.h> | 11 | #include <asm/hpet.h> |
12 | #include <asm/timex.h> | 12 | #include <asm/timex.h> |
13 | #include <asm/timer.h> | 13 | #include <asm/timer.h> |
14 | #include <asm/vgtod.h> | ||
15 | 14 | ||
16 | static int notsc __initdata = 0; | 15 | static int notsc __initdata = 0; |
17 | 16 | ||
@@ -149,9 +148,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | |||
149 | mark_tsc_unstable("cpufreq changes"); | 148 | mark_tsc_unstable("cpufreq changes"); |
150 | } | 149 | } |
151 | 150 | ||
152 | preempt_disable(); | 151 | set_cyc2ns_scale(tsc_khz_ref, freq->cpu); |
153 | set_cyc2ns_scale(tsc_khz_ref, smp_processor_id()); | ||
154 | preempt_enable(); | ||
155 | 152 | ||
156 | return 0; | 153 | return 0; |
157 | } | 154 | } |
@@ -291,34 +288,18 @@ int __init notsc_setup(char *s) | |||
291 | 288 | ||
292 | __setup("notsc", notsc_setup); | 289 | __setup("notsc", notsc_setup); |
293 | 290 | ||
294 | static struct clocksource clocksource_tsc; | ||
295 | 291 | ||
296 | /* | 292 | /* clock source code: */ |
297 | * We compare the TSC to the cycle_last value in the clocksource | ||
298 | * structure to avoid a nasty time-warp. This can be observed in a | ||
299 | * very small window right after one CPU updated cycle_last under | ||
300 | * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which | ||
301 | * is smaller than the cycle_last reference value due to a TSC which | ||
302 | * is slighty behind. This delta is nowhere else observable, but in | ||
303 | * that case it results in a forward time jump in the range of hours | ||
304 | * due to the unsigned delta calculation of the time keeping core | ||
305 | * code, which is necessary to support wrapping clocksources like pm | ||
306 | * timer. | ||
307 | */ | ||
308 | static cycle_t read_tsc(void) | 293 | static cycle_t read_tsc(void) |
309 | { | 294 | { |
310 | cycle_t ret = (cycle_t)get_cycles(); | 295 | cycle_t ret = (cycle_t)get_cycles(); |
311 | 296 | return ret; | |
312 | return ret >= clocksource_tsc.cycle_last ? | ||
313 | ret : clocksource_tsc.cycle_last; | ||
314 | } | 297 | } |
315 | 298 | ||
316 | static cycle_t __vsyscall_fn vread_tsc(void) | 299 | static cycle_t __vsyscall_fn vread_tsc(void) |
317 | { | 300 | { |
318 | cycle_t ret = (cycle_t)vget_cycles(); | 301 | cycle_t ret = (cycle_t)vget_cycles(); |
319 | 302 | return ret; | |
320 | return ret >= __vsyscall_gtod_data.clock.cycle_last ? | ||
321 | ret : __vsyscall_gtod_data.clock.cycle_last; | ||
322 | } | 303 | } |
323 | 304 | ||
324 | static struct clocksource clocksource_tsc = { | 305 | static struct clocksource clocksource_tsc = { |