aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/tsc_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/tsc_64.c')
-rw-r--r--arch/x86/kernel/tsc_64.c27
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
16static int notsc __initdata = 0; 15static 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
294static 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 */
308static cycle_t read_tsc(void) 293static 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
316static cycle_t __vsyscall_fn vread_tsc(void) 299static 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
324static struct clocksource clocksource_tsc = { 305static struct clocksource clocksource_tsc = {