softlockup: fix softlockup_thresh unaligned access and disable detection at runtime
Dimitri Sivanich [Mon, 12 May 2008 19:21:14 +0000 (21:21 +0200)]
Fix unaligned access errors when setting softlockup_thresh on
64 bit platforms.

Allow softlockup detection to be disabled by setting
softlockup_thresh <= 0.

Detect that boot time softlockup detection has been disabled
earlier in softlockup_tick.

Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

include/linux/sched.h
kernel/softlockup.c
kernel/sysctl.c

index 71f5972..ea26221 100644 (file)
@@ -295,10 +295,10 @@ extern void spawn_softlockup_task(void);
 extern void touch_softlockup_watchdog(void);
 extern void touch_all_softlockup_watchdogs(void);
 extern unsigned int  softlockup_panic;
-extern unsigned long softlockup_thresh;
 extern unsigned long sysctl_hung_task_check_count;
 extern unsigned long sysctl_hung_task_timeout_secs;
 extern unsigned long sysctl_hung_task_warnings;
+extern int softlockup_thresh;
 #else
 static inline void softlockup_tick(void)
 {
index 78e0ad2..a3a0b23 100644 (file)
@@ -25,7 +25,7 @@ static DEFINE_PER_CPU(unsigned long, print_timestamp);
 static DEFINE_PER_CPU(struct task_struct *, watchdog_task);
 
 static int __read_mostly did_panic;
-unsigned long __read_mostly softlockup_thresh = 60;
+int __read_mostly softlockup_thresh = 60;
 
 /*
  * Should we panic (and reboot, if panic_timeout= is set) when a
@@ -94,6 +94,14 @@ void softlockup_tick(void)
        struct pt_regs *regs = get_irq_regs();
        unsigned long now;
 
+       /* Is detection switched off? */
+       if (!per_cpu(watchdog_task, this_cpu) || softlockup_thresh <= 0) {
+               /* Be sure we don't false trigger if switched back on */
+               if (touch_timestamp)
+                       per_cpu(touch_timestamp, this_cpu) = 0;
+               return;
+       }
+
        if (touch_timestamp == 0) {
                touch_softlockup_watchdog();
                return;
@@ -104,7 +112,7 @@ void softlockup_tick(void)
        /* report at most once a second */
        if ((print_timestamp >= touch_timestamp &&
                        print_timestamp < (touch_timestamp + 1)) ||
-                       did_panic || !per_cpu(watchdog_task, this_cpu)) {
+                       did_panic) {
                return;
        }
 
index 2d3b388..31c19a7 100644 (file)
@@ -84,12 +84,13 @@ extern int latencytop_enabled;
 extern int sysctl_nr_open_min, sysctl_nr_open_max;
 
 /* Constants used for minimum and  maximum */
-#if defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM)
+#ifdef CONFIG_HIGHMEM
 static int one = 1;
 #endif
 
 #ifdef CONFIG_DETECT_SOFTLOCKUP
 static int sixty = 60;
+static int neg_one = -1;
 #endif
 
 #ifdef CONFIG_MMU
@@ -742,11 +743,11 @@ static struct ctl_table kern_table[] = {
                .ctl_name       = CTL_UNNUMBERED,
                .procname       = "softlockup_thresh",
                .data           = &softlockup_thresh,
-               .maxlen         = sizeof(unsigned long),
+               .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_doulongvec_minmax,
+               .proc_handler   = &proc_dointvec_minmax,
                .strategy       = &sysctl_intvec,
-               .extra1         = &one,
+               .extra1         = &neg_one,
                .extra2         = &sixty,
        },
        {