kernel/watchdog.c: Use proper ANSI C prototypes
[pandora-kernel.git] / kernel / watchdog.c
index 14733d4..7daa4b0 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/perf_event.h>
 
 int watchdog_enabled = 1;
-int __read_mostly softlockup_thresh = 60;
+int __read_mostly watchdog_thresh = 10;
 
 static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts);
 static DEFINE_PER_CPU(struct task_struct *, softlockup_watchdog);
@@ -91,6 +91,17 @@ static int __init nosoftlockup_setup(char *str)
 __setup("nosoftlockup", nosoftlockup_setup);
 /*  */
 
+/*
+ * Hard-lockup warnings should be triggered after just a few seconds. Soft-
+ * lockups can have false positives under extreme conditions. So we generally
+ * want a higher threshold for soft lockups than for hard lockups. So we couple
+ * the thresholds with a factor: we make the soft threshold twice the amount of
+ * time the hard threshold is.
+ */
+static int get_softlockup_thresh(void)
+{
+       return watchdog_thresh * 2;
+}
 
 /*
  * Returns seconds, approximately.  We don't need nanosecond
@@ -105,12 +116,12 @@ static unsigned long get_timestamp(int this_cpu)
 static unsigned long get_sample_period(void)
 {
        /*
-        * convert softlockup_thresh from seconds to ns
+        * convert watchdog_thresh from seconds to ns
         * the divide by 5 is to give hrtimer 5 chances to
         * increment before the hardlockup detector generates
         * a warning
         */
-       return softlockup_thresh / 5 * NSEC_PER_SEC;
+       return get_softlockup_thresh() * (NSEC_PER_SEC / 5);
 }
 
 /* Commands for resetting the watchdog */
@@ -182,7 +193,7 @@ static int is_softlockup(unsigned long touch_ts)
        unsigned long now = get_timestamp(smp_processor_id());
 
        /* Warn about unreasonable delays: */
-       if (time_after(now, touch_ts + softlockup_thresh))
+       if (time_after(now, touch_ts + get_softlockup_thresh()))
                return now - touch_ts;
 
        return 0;
@@ -359,7 +370,7 @@ static int watchdog_nmi_enable(int cpu)
 
        /* Try to register using hardware perf events */
        wd_attr = &wd_hw_attr;
-       wd_attr->sample_period = hw_nmi_get_sample_period();
+       wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
        event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback);
        if (!IS_ERR(event)) {
                printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n");
@@ -501,28 +512,25 @@ static void watchdog_disable_all_cpus(void)
 /* sysctl functions */
 #ifdef CONFIG_SYSCTL
 /*
- * proc handler for /proc/sys/kernel/nmi_watchdog
+ * proc handler for /proc/sys/kernel/nmi_watchdog,watchdog_thresh
  */
 
-int proc_dowatchdog_enabled(struct ctl_table *table, int write,
-                    void __user *buffer, size_t *length, loff_t *ppos)
+int proc_dowatchdog(struct ctl_table *table, int write,
+                   void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       proc_dointvec(table, write, buffer, length, ppos);
+       int ret;
 
-       if (write) {
-               if (watchdog_enabled)
-                       watchdog_enable_all_cpus();
-               else
-                       watchdog_disable_all_cpus();
-       }
-       return 0;
-}
+       ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+       if (ret || !write)
+               goto out;
 
-int proc_dowatchdog_thresh(struct ctl_table *table, int write,
-                            void __user *buffer,
-                            size_t *lenp, loff_t *ppos)
-{
-       return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+       if (watchdog_enabled && watchdog_thresh)
+               watchdog_enable_all_cpus();
+       else
+               watchdog_disable_all_cpus();
+
+out:
+       return ret;
 }
 #endif /* CONFIG_SYSCTL */