diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-02-16 04:27:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-16 11:13:57 -0500 |
commit | 5d8b34fdcb384161552d01ee8f34af5ff11f9684 (patch) | |
tree | 7052d50574d747b7ec2172051adf8126074d6982 /arch/i386 | |
parent | 7e69f2b1ead2a4c51c12817f18263ff0e59335a6 (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/Kconfig | 4 | ||||
-rw-r--r-- | arch/i386/kernel/tsc.c | 49 |
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 | ||
21 | config CLOCKSOURCE_WATCHDOG | ||
22 | bool | ||
23 | default y | ||
24 | |||
21 | config LOCKDEP_SUPPORT | 25 | config 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 */ | ||
348 | static struct timer_list verify_tsc_freq_timer; | ||
349 | |||
350 | /* XXX - Probably should add locking */ | ||
351 | static 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 | |||
382 | out: | ||
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 | ||