aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/panic.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/panic.c')
-rw-r--r--kernel/panic.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/kernel/panic.c b/kernel/panic.c
index 5827f7b97254..13d966b4c14a 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -36,15 +36,36 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list);
36 36
37EXPORT_SYMBOL(panic_notifier_list); 37EXPORT_SYMBOL(panic_notifier_list);
38 38
39static long no_blink(long time)
40{
41 return 0;
42}
43
44/* Returns how long it waited in ms */ 39/* Returns how long it waited in ms */
45long (*panic_blink)(long time); 40long (*panic_blink)(long time);
46EXPORT_SYMBOL(panic_blink); 41EXPORT_SYMBOL(panic_blink);
47 42
43static void panic_blink_one_second(void)
44{
45 static long i = 0, end;
46
47 if (panic_blink) {
48 end = i + MSEC_PER_SEC;
49
50 while (i < end) {
51 i += panic_blink(i);
52 mdelay(1);
53 i++;
54 }
55 } else {
56 /*
57 * When running under a hypervisor a small mdelay may get
58 * rounded up to the hypervisor timeslice. For example, with
59 * a 1ms in 10ms hypervisor timeslice we might inflate a
60 * mdelay(1) loop by 10x.
61 *
62 * If we have nothing to blink, spin on 1 second calls to
63 * mdelay to avoid this.
64 */
65 mdelay(MSEC_PER_SEC);
66 }
67}
68
48/** 69/**
49 * panic - halt the system 70 * panic - halt the system
50 * @fmt: The text string to print 71 * @fmt: The text string to print
@@ -75,7 +96,6 @@ NORET_TYPE void panic(const char * fmt, ...)
75 dump_stack(); 96 dump_stack();
76#endif 97#endif
77 98
78 kmsg_dump(KMSG_DUMP_PANIC);
79 /* 99 /*
80 * If we have crashed and we have a crash kernel loaded let it handle 100 * If we have crashed and we have a crash kernel loaded let it handle
81 * everything else. 101 * everything else.
@@ -83,6 +103,8 @@ NORET_TYPE void panic(const char * fmt, ...)
83 */ 103 */
84 crash_kexec(NULL); 104 crash_kexec(NULL);
85 105
106 kmsg_dump(KMSG_DUMP_PANIC);
107
86 /* 108 /*
87 * Note smp_send_stop is the usual smp shutdown function, which 109 * Note smp_send_stop is the usual smp shutdown function, which
88 * unfortunately means it may not be hardened to work in a panic 110 * unfortunately means it may not be hardened to work in a panic
@@ -94,9 +116,6 @@ NORET_TYPE void panic(const char * fmt, ...)
94 116
95 bust_spinlocks(0); 117 bust_spinlocks(0);
96 118
97 if (!panic_blink)
98 panic_blink = no_blink;
99
100 if (panic_timeout > 0) { 119 if (panic_timeout > 0) {
101 /* 120 /*
102 * Delay timeout seconds before rebooting the machine. 121 * Delay timeout seconds before rebooting the machine.
@@ -104,11 +123,9 @@ NORET_TYPE void panic(const char * fmt, ...)
104 */ 123 */
105 printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout); 124 printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);
106 125
107 for (i = 0; i < panic_timeout*1000; ) { 126 for (i = 0; i < panic_timeout; i++) {
108 touch_nmi_watchdog(); 127 touch_nmi_watchdog();
109 i += panic_blink(i); 128 panic_blink_one_second();
110 mdelay(1);
111 i++;
112 } 129 }
113 /* 130 /*
114 * This will not be a clean reboot, with everything 131 * This will not be a clean reboot, with everything
@@ -134,11 +151,9 @@ NORET_TYPE void panic(const char * fmt, ...)
134 } 151 }
135#endif 152#endif
136 local_irq_enable(); 153 local_irq_enable();
137 for (i = 0; ; ) { 154 while (1) {
138 touch_softlockup_watchdog(); 155 touch_softlockup_watchdog();
139 i += panic_blink(i); 156 panic_blink_one_second();
140 mdelay(1);
141 i++;
142 } 157 }
143} 158}
144 159