|
@@ -24,6 +24,9 @@
|
|
|
#include <linux/nmi.h>
|
|
|
#include <linux/dmi.h>
|
|
|
|
|
|
+#define PANIC_TIMER_STEP 100
|
|
|
+#define PANIC_BLINK_SPD 18
|
|
|
+
|
|
|
int panic_on_oops;
|
|
|
static unsigned long tainted_mask;
|
|
|
static int pause_on_oops;
|
|
@@ -36,36 +39,15 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
|
|
|
|
|
|
EXPORT_SYMBOL(panic_notifier_list);
|
|
|
|
|
|
-/* Returns how long it waited in ms */
|
|
|
-long (*panic_blink)(long time);
|
|
|
-EXPORT_SYMBOL(panic_blink);
|
|
|
-
|
|
|
-static void panic_blink_one_second(void)
|
|
|
+static long no_blink(int state)
|
|
|
{
|
|
|
- static long i = 0, end;
|
|
|
-
|
|
|
- if (panic_blink) {
|
|
|
- end = i + MSEC_PER_SEC;
|
|
|
-
|
|
|
- while (i < end) {
|
|
|
- i += panic_blink(i);
|
|
|
- mdelay(1);
|
|
|
- i++;
|
|
|
- }
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * When running under a hypervisor a small mdelay may get
|
|
|
- * rounded up to the hypervisor timeslice. For example, with
|
|
|
- * a 1ms in 10ms hypervisor timeslice we might inflate a
|
|
|
- * mdelay(1) loop by 10x.
|
|
|
- *
|
|
|
- * If we have nothing to blink, spin on 1 second calls to
|
|
|
- * mdelay to avoid this.
|
|
|
- */
|
|
|
- mdelay(MSEC_PER_SEC);
|
|
|
- }
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
+/* Returns how long it waited in ms */
|
|
|
+long (*panic_blink)(int state);
|
|
|
+EXPORT_SYMBOL(panic_blink);
|
|
|
+
|
|
|
/**
|
|
|
* panic - halt the system
|
|
|
* @fmt: The text string to print
|
|
@@ -78,7 +60,8 @@ NORET_TYPE void panic(const char * fmt, ...)
|
|
|
{
|
|
|
static char buf[1024];
|
|
|
va_list args;
|
|
|
- long i;
|
|
|
+ long i, i_next = 0;
|
|
|
+ int state = 0;
|
|
|
|
|
|
/*
|
|
|
* It's possible to come here directly from a panic-assertion and
|
|
@@ -117,6 +100,9 @@ NORET_TYPE void panic(const char * fmt, ...)
|
|
|
|
|
|
bust_spinlocks(0);
|
|
|
|
|
|
+ if (!panic_blink)
|
|
|
+ panic_blink = no_blink;
|
|
|
+
|
|
|
if (panic_timeout > 0) {
|
|
|
/*
|
|
|
* Delay timeout seconds before rebooting the machine.
|
|
@@ -124,9 +110,13 @@ NORET_TYPE void panic(const char * fmt, ...)
|
|
|
*/
|
|
|
printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);
|
|
|
|
|
|
- for (i = 0; i < panic_timeout; i++) {
|
|
|
+ for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) {
|
|
|
touch_nmi_watchdog();
|
|
|
- panic_blink_one_second();
|
|
|
+ if (i >= i_next) {
|
|
|
+ i += panic_blink(state ^= 1);
|
|
|
+ i_next = i + 3600 / PANIC_BLINK_SPD;
|
|
|
+ }
|
|
|
+ mdelay(PANIC_TIMER_STEP);
|
|
|
}
|
|
|
/*
|
|
|
* This will not be a clean reboot, with everything
|
|
@@ -152,9 +142,13 @@ NORET_TYPE void panic(const char * fmt, ...)
|
|
|
}
|
|
|
#endif
|
|
|
local_irq_enable();
|
|
|
- while (1) {
|
|
|
+ for (i = 0; ; i += PANIC_TIMER_STEP) {
|
|
|
touch_softlockup_watchdog();
|
|
|
- panic_blink_one_second();
|
|
|
+ if (i >= i_next) {
|
|
|
+ i += panic_blink(state ^= 1);
|
|
|
+ i_next = i + 3600 / PANIC_BLINK_SPD;
|
|
|
+ }
|
|
|
+ mdelay(PANIC_TIMER_STEP);
|
|
|
}
|
|
|
}
|
|
|
|