]> rtime.felk.cvut.cz Git - zynq/linux.git/blobdiff - kernel/watchdog.c
Merge branch '4.0.8-rt6'
[zynq/linux.git] / kernel / watchdog.c
index 3174bf8e353852ae886743b8ffbe33e46fb03c02..4b7575d1b1c6bc72c15184488641808502701dba 100644 (file)
@@ -248,6 +248,8 @@ static int is_softlockup(unsigned long touch_ts)
 
 #ifdef CONFIG_HARDLOCKUP_DETECTOR
 
+static DEFINE_RAW_SPINLOCK(watchdog_output_lock);
+
 static struct perf_event_attr wd_hw_attr = {
        .type           = PERF_TYPE_HARDWARE,
        .config         = PERF_COUNT_HW_CPU_CYCLES,
@@ -281,13 +283,21 @@ static void watchdog_overflow_callback(struct perf_event *event,
                /* only print hardlockups once */
                if (__this_cpu_read(hard_watchdog_warn) == true)
                        return;
+               /*
+                * If early-printk is enabled then make sure we do not
+                * lock up in printk() and kill console logging:
+                */
+               printk_kill();
 
-               if (hardlockup_panic)
+               if (hardlockup_panic) {
                        panic("Watchdog detected hard LOCKUP on cpu %d",
                              this_cpu);
-               else
+               } else {
+                       raw_spin_lock(&watchdog_output_lock);
                        WARN(1, "Watchdog detected hard LOCKUP on cpu %d",
                             this_cpu);
+                       raw_spin_unlock(&watchdog_output_lock);
+               }
 
                __this_cpu_write(hard_watchdog_warn, true);
                return;
@@ -430,6 +440,7 @@ static void watchdog_enable(unsigned int cpu)
        /* kick off the timer for the hardlockup detector */
        hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        hrtimer->function = watchdog_timer_fn;
+       hrtimer->irqsafe = 1;
 
        /* Enable the perf event */
        watchdog_nmi_enable(cpu);