OSDN Git Service

futex: futex_wake_op, do not fail on invalid op
[uclinux-h8/linux.git] / kernel / watchdog.c
index f6ef163..6bcb854 100644 (file)
@@ -47,7 +47,6 @@ int __read_mostly watchdog_thresh = 10;
 int __read_mostly nmi_watchdog_available;
 
 struct cpumask watchdog_allowed_mask __read_mostly;
-static bool softlockup_threads_initialized __read_mostly;
 
 struct cpumask watchdog_cpumask __read_mostly;
 unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
@@ -123,24 +122,27 @@ int __weak __init watchdog_nmi_probe(void)
 }
 
 /**
- * watchdog_nmi_reconfigure - Optional function to reconfigure NMI watchdogs
- * @run:       If false stop the watchdogs on all enabled CPUs
- *             If true start the watchdogs on all enabled CPUs
+ * watchdog_nmi_stop - Stop the watchdog for reconfiguration
  *
- * The core call order is:
- * watchdog_nmi_reconfigure(false);
+ * The reconfiguration steps are:
+ * watchdog_nmi_stop();
  * update_variables();
- * watchdog_nmi_reconfigure(true);
+ * watchdog_nmi_start();
+ */
+void __weak watchdog_nmi_stop(void) { }
+
+/**
+ * watchdog_nmi_start - Start the watchdog after reconfiguration
  *
- * The second call which starts the watchdogs again guarantees that the
- * following variables are stable across the call.
+ * Counterpart to watchdog_nmi_stop().
+ *
+ * The following variables have been updated in update_variables() and
+ * contain the currently valid configuration:
  * - watchdog_enabled
  * - watchdog_thresh
  * - watchdog_cpumask
- *
- * After the call the variables can be changed again.
  */
-void __weak watchdog_nmi_reconfigure(bool run) { }
+void __weak watchdog_nmi_start(void) { }
 
 /**
  * lockup_detector_update_enable - Update the sysctl enable bit
@@ -165,6 +167,7 @@ static void lockup_detector_update_enable(void)
 unsigned int __read_mostly softlockup_panic =
                        CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE;
 
+static bool softlockup_threads_initialized __read_mostly;
 static u64 __read_mostly sample_period;
 
 static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts);
@@ -532,7 +535,6 @@ static void softlockup_update_smpboot_threads(void)
 
        smpboot_update_cpumask_percpu_thread(&watchdog_threads,
                                             &watchdog_allowed_mask);
-       __lockup_detector_cleanup();
 }
 
 /* Temporarily park all watchdog threads */
@@ -549,25 +551,32 @@ static void softlockup_unpark_threads(void)
        softlockup_update_smpboot_threads();
 }
 
-static void softlockup_reconfigure_threads(void)
+static void lockup_detector_reconfigure(void)
 {
-       watchdog_nmi_reconfigure(false);
+       cpus_read_lock();
+       watchdog_nmi_stop();
        softlockup_park_all_threads();
        set_sample_period();
        lockup_detector_update_enable();
        if (watchdog_enabled && watchdog_thresh)
                softlockup_unpark_threads();
-       watchdog_nmi_reconfigure(true);
+       watchdog_nmi_start();
+       cpus_read_unlock();
+       /*
+        * Must be called outside the cpus locked section to prevent
+        * recursive locking in the perf code.
+        */
+       __lockup_detector_cleanup();
 }
 
 /*
- * Create the watchdog thread infrastructure.
+ * Create the watchdog thread infrastructure and configure the detector(s).
  *
  * The threads are not unparked as watchdog_allowed_mask is empty.  When
  * the threads are sucessfully initialized, take the proper locks and
  * unpark the threads in the watchdog_cpumask if the watchdog is enabled.
  */
-static __init void softlockup_init_threads(void)
+static __init void lockup_detector_setup(void)
 {
        int ret;
 
@@ -590,7 +599,7 @@ static __init void softlockup_init_threads(void)
 
        mutex_lock(&watchdog_mutex);
        softlockup_threads_initialized = true;
-       softlockup_reconfigure_threads();
+       lockup_detector_reconfigure();
        mutex_unlock(&watchdog_mutex);
 }
 
@@ -599,12 +608,17 @@ static inline int watchdog_park_threads(void) { return 0; }
 static inline void watchdog_unpark_threads(void) { }
 static inline int watchdog_enable_all_cpus(void) { return 0; }
 static inline void watchdog_disable_all_cpus(void) { }
-static inline void softlockup_init_threads(void) { }
-static void softlockup_reconfigure_threads(void)
+static void lockup_detector_reconfigure(void)
 {
-       watchdog_nmi_reconfigure(false);
+       cpus_read_lock();
+       watchdog_nmi_stop();
        lockup_detector_update_enable();
-       watchdog_nmi_reconfigure(true);
+       watchdog_nmi_start();
+       cpus_read_unlock();
+}
+static inline void lockup_detector_setup(void)
+{
+       lockup_detector_reconfigure();
 }
 #endif /* !CONFIG_SOFTLOCKUP_DETECTOR */
 
@@ -644,7 +658,7 @@ static void proc_watchdog_update(void)
 {
        /* Remove impossible cpus to keep sysctl output clean. */
        cpumask_and(&watchdog_cpumask, &watchdog_cpumask, cpu_possible_mask);
-       softlockup_reconfigure_threads();
+       lockup_detector_reconfigure();
 }
 
 /*
@@ -771,5 +785,5 @@ void __init lockup_detector_init(void)
 
        if (!watchdog_nmi_probe())
                nmi_watchdog_available = true;
-       softlockup_init_threads();
+       lockup_detector_setup();
 }