aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-02-16 04:27:43 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:13:57 -0500
commit5d8b34fdcb384161552d01ee8f34af5ff11f9684 (patch)
tree7052d50574d747b7ec2172051adf8126074d6982 /arch/i386
parent7e69f2b1ead2a4c51c12817f18263ff0e59335a6 (diff)
[PATCH] clocksource: Add verification (watchdog) helper
The TSC needs to be verified against another clocksource. Instead of using hardwired assumptions of available hardware, provide a generic verification mechanism. The verification uses the best available clocksource and handles the usability for high resolution timers / dynticks of the clocksource which needs to be verified. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: john stultz <johnstul@us.ibm.com> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/Kconfig4
-rw-r--r--arch/i386/kernel/tsc.c49
2 files changed, 4 insertions, 49 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 4ea31c327d1f..458b3aad3eb3 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -18,6 +18,10 @@ config GENERIC_TIME
18 bool 18 bool
19 default y 19 default y
20 20
21config CLOCKSOURCE_WATCHDOG
22 bool
23 default y
24
21config LOCKDEP_SUPPORT 25config LOCKDEP_SUPPORT
22 bool 26 bool
23 default y 27 default y
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index b4b2be21d1c7..22931d24027c 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -344,49 +344,6 @@ static struct dmi_system_id __initdata bad_tsc_dmi_table[] = {
344 {} 344 {}
345}; 345};
346 346
347#define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */
348static struct timer_list verify_tsc_freq_timer;
349
350/* XXX - Probably should add locking */
351static void verify_tsc_freq(unsigned long unused)
352{
353 static u64 last_tsc;
354 static unsigned long last_jiffies;
355
356 u64 now_tsc, interval_tsc;
357 unsigned long now_jiffies, interval_jiffies;
358
359
360 if (check_tsc_unstable())
361 return;
362
363 rdtscll(now_tsc);
364 now_jiffies = jiffies;
365
366 if (!last_jiffies) {
367 goto out;
368 }
369
370 interval_jiffies = now_jiffies - last_jiffies;
371 interval_tsc = now_tsc - last_tsc;
372 interval_tsc *= HZ;
373 do_div(interval_tsc, cpu_khz*1000);
374
375 if (interval_tsc < (interval_jiffies * 3 / 4)) {
376 printk("TSC appears to be running slowly. "
377 "Marking it as unstable\n");
378 mark_tsc_unstable();
379 return;
380 }
381
382out:
383 last_tsc = now_tsc;
384 last_jiffies = now_jiffies;
385 /* set us up to go off on the next interval: */
386 mod_timer(&verify_tsc_freq_timer,
387 jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL));
388}
389
390/* 347/*
391 * Make an educated guess if the TSC is trustworthy and synchronized 348 * Make an educated guess if the TSC is trustworthy and synchronized
392 * over all CPUs. 349 * over all CPUs.
@@ -424,12 +381,6 @@ static int __init init_tsc_clocksource(void)
424 clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; 381 clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS;
425 } 382 }
426 383
427 init_timer(&verify_tsc_freq_timer);
428 verify_tsc_freq_timer.function = verify_tsc_freq;
429 verify_tsc_freq_timer.expires =
430 jiffies + msecs_to_jiffies(TSC_FREQ_CHECK_INTERVAL);
431 add_timer(&verify_tsc_freq_timer);
432
433 return clocksource_register(&clocksource_tsc); 384 return clocksource_register(&clocksource_tsc);
434 } 385 }
435 386