diff options
Diffstat (limited to 'drivers/char/hangcheck-timer.c')
| -rw-r--r-- | drivers/char/hangcheck-timer.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index 66e53dd450f..f953c96efc8 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c @@ -26,7 +26,7 @@ * The hangcheck-timer driver uses the TSC to catch delays that * jiffies does not notice. A timer is set. When the timer fires, it * checks whether it was delayed and if that delay exceeds a given - * margin of error. The hangcheck_tick module paramter takes the timer + * margin of error. The hangcheck_tick module parameter takes the timer * duration in seconds. The hangcheck_margin parameter defines the * margin of error, in seconds. The defaults are 60 seconds for the * timer and 180 seconds for the margin of error. IOW, a timer is set @@ -44,14 +44,14 @@ #include <linux/fs.h> #include <linux/mm.h> #include <linux/reboot.h> -#include <linux/smp_lock.h> #include <linux/init.h> #include <linux/delay.h> #include <asm/uaccess.h> #include <linux/sysrq.h> +#include <linux/timer.h> +#include <linux/time.h> - -#define VERSION_STR "0.9.0" +#define VERSION_STR "0.9.1" #define DEFAULT_IOFENCE_MARGIN 60 /* Default fudge factor, in seconds */ #define DEFAULT_IOFENCE_TICK 180 /* Default timer timeout, in seconds */ @@ -117,16 +117,11 @@ __setup("hcheck_reboot", hangcheck_parse_reboot); __setup("hcheck_dump_tasks", hangcheck_parse_dump_tasks); #endif /* not MODULE */ -#if defined(CONFIG_X86) +#if defined(CONFIG_S390) # define HAVE_MONOTONIC # define TIMER_FREQ 1000000000ULL -#elif defined(CONFIG_ARCH_S390) -/* FA240000 is 1 Second in the IBM time universe (Page 4-38 Principles of Op for zSeries */ -# define TIMER_FREQ 0xFA240000ULL -#elif defined(CONFIG_IA64) -# define TIMER_FREQ ((unsigned long long)local_cpu_data->itc_freq) -#elif defined(CONFIG_PPC64) -# define TIMER_FREQ (HZ*loops_per_jiffy) +#else +# define TIMER_FREQ 1000000000ULL #endif #ifdef HAVE_MONOTONIC @@ -134,12 +129,9 @@ extern unsigned long long monotonic_clock(void); #else static inline unsigned long long monotonic_clock(void) { -# ifdef __s390__ - /* returns the TOD. see 4-38 Principles of Op of zSeries */ - return get_clock(); -# else - return get_cycles(); -# endif /* __s390__ */ + struct timespec ts; + getrawmonotonic(&ts); + return timespec_to_ns(&ts); } #endif /* HAVE_MONOTONIC */ @@ -167,7 +159,7 @@ static void hangcheck_fire(unsigned long data) if (hangcheck_dump_tasks) { printk(KERN_CRIT "Hangcheck: Task state:\n"); #ifdef CONFIG_MAGIC_SYSRQ - handle_sysrq('t', NULL, NULL); + handle_sysrq('t'); #endif /* CONFIG_MAGIC_SYSRQ */ } if (hangcheck_reboot) { @@ -177,6 +169,13 @@ static void hangcheck_fire(unsigned long data) printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n"); } } +#if 0 + /* + * Enable to investigate delays in detail + */ + printk("Hangcheck: called %Ld ns since last time (%Ld ns overshoot)\n", + tsc_diff, tsc_diff - hangcheck_tick*TIMER_FREQ); +#endif mod_timer(&hangcheck_ticktock, jiffies + (hangcheck_tick*HZ)); hangcheck_tsc = monotonic_clock(); } @@ -188,10 +187,8 @@ static int __init hangcheck_init(void) VERSION_STR, hangcheck_tick, hangcheck_margin); #if defined (HAVE_MONOTONIC) printk("Hangcheck: Using monotonic_clock().\n"); -#elif defined(__s390__) - printk("Hangcheck: Using TOD.\n"); #else - printk("Hangcheck: Using get_cycles().\n"); + printk("Hangcheck: Using getrawmonotonic().\n"); #endif /* HAVE_MONOTONIC */ hangcheck_tsc_margin = (unsigned long long)(hangcheck_margin + hangcheck_tick); |
