8 #include <linux/kernel.h>
13 #include <linux/export.h>
16 #include <linux/reboot.h>
17 #include <linux/slab.h>
22 #include <asm/perf_event.h>
23 #include <asm/ptrace.h>
36 static int panic_on_timeout;
46 static unsigned int nmi_hz =
HZ;
60 if (
per_cpu(nmi_touch, cpu) != 1)
69 static void die_nmi(
const char *
str,
struct pt_regs *
regs,
int do_panic)
72 pt_regs_trap_type(regs),
SIGINT) == NOTIFY_STOP)
79 printk(
" on CPU%d, ip %08lx, registers:\n",
87 panic(
"Non maskable interrupt");
96 unsigned int sum, touched = 0;
99 clear_softint(1 << irq);
105 orig_sp = set_hardirq_stack();
108 pt_regs_trap_type(regs),
SIGINT) == NOTIFY_STOP)
121 die_nmi(
"BUG: NMI Watchdog detected LOCKUP",
122 regs, panic_on_timeout);
132 restore_hardirq_stack(orig_sp);
137 static inline unsigned int get_nmi_count(
int cpu)
149 static void report_broken_nmi(
int cpu,
int *prev_nmi_count)
154 "WARNING: CPU#%d: NMI appears to be stuck (%d->%d)!\n",
155 cpu, prev_nmi_count[cpu], get_nmi_count(cpu));
158 "Please report this to bugzilla.kernel.org,\n");
160 "and attach the output of the 'dmesg' command.\n");
173 static int __init check_nmi_watchdog(
void)
175 unsigned int *prev_nmi_count;
182 if (!prev_nmi_count) {
192 prev_nmi_count[cpu] = get_nmi_count(cpu);
194 mdelay((20 * 1000) / nmi_hz);
199 if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
200 report_broken_nmi(cpu, prev_nmi_count);
204 kfree(prev_nmi_count);
213 kfree(prev_nmi_count);
231 static void nmi_adjust_hz_one(
void *
unused)
256 .notifier_call = nmi_shutdown,
265 err = check_nmi_watchdog();
277 static int __init setup_nmi_watchdog(
char *str)
280 panic_on_timeout = 1;
284 __setup(
"nmi_watchdog=", setup_nmi_watchdog);