[RFC][PATCH] nmi watchdog: handle NMI_IO_APIC on nmi_watchdog

Aristeu Rozanski <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.smp
Message-ID <[email protected]>
(Resend)
This patch includes code to handle NMI_IO_APIC enabling/disabling by
nmi_watchdog proc file.

Signed-off-by: Aristeu Rozanski <[email protected]>

---
 arch/x86/kernel/nmi_32.c |   25 +++++++++++++++++++++++++
 arch/x86/kernel/nmi_64.c |   25 +++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

--- nmi.orig/arch/x86/kernel/nmi_64.c	2008-03-12 17:02:36.000000000 -0400
+++ nmi/arch/x86/kernel/nmi_64.c	2008-03-12 17:47:35.000000000 -0400
@@ -274,6 +274,8 @@ void stop_apic_nmi_watchdog(void *unused
 		return;
 	if (nmi_watchdog == NMI_LOCAL_APIC)
 		lapic_watchdog_stop();
+	else
+		__acpi_nmi_disable(NULL);
 	__get_cpu_var(wd_enabled) = 0;
 	atomic_dec(&nmi_active);
 }
@@ -405,6 +407,24 @@ void restart_nmi(void)
 
 #ifdef CONFIG_SYSCTL
 
+static void enable_ioapic_nmi_watchdog_single(void *unused)
+{
+	__get_cpu_var(wd_enabled) = 1;
+	atomic_inc(&nmi_active);
+	__acpi_nmi_enable(NULL);
+}
+
+static void enable_ioapic_nmi_watchdog(void)
+{
+	on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 0, 1);
+	touch_nmi_watchdog();
+}
+
+static void disable_ioapic_nmi_watchdog(void)
+{
+	on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
+}
+
 static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
 {
 	unsigned char reason = get_nmi_reason();
@@ -442,6 +462,11 @@ int proc_nmi_enabled(struct ctl_table *t
 			enable_lapic_nmi_watchdog();
 		else
 			disable_lapic_nmi_watchdog();
+	} else if (nmi_watchdog == NMI_IO_APIC) {
+		if (nmi_watchdog_enabled)
+			enable_ioapic_nmi_watchdog();
+		else
+			disable_ioapic_nmi_watchdog();
 	} else {
 		printk( KERN_WARNING
 			"NMI watchdog doesn't know what hardware to touch\n");
--- nmi.orig/arch/x86/kernel/nmi_32.c	2008-03-12 15:16:30.000000000 -0400
+++ nmi/arch/x86/kernel/nmi_32.c	2008-03-12 17:50:55.000000000 -0400
@@ -270,6 +270,8 @@ void stop_apic_nmi_watchdog(void *unused
 		return;
 	if (nmi_watchdog == NMI_LOCAL_APIC)
 		lapic_watchdog_stop();
+	else
+		__acpi_nmi_disable(NULL);
 	__get_cpu_var(wd_enabled) = 0;
 	atomic_dec(&nmi_active);
 }
@@ -390,6 +392,24 @@ __kprobes int nmi_watchdog_tick(struct p
 
 #ifdef CONFIG_SYSCTL
 
+static void enable_ioapic_nmi_watchdog_single(void *unused)
+{
+	__get_cpu_var(wd_enabled) = 1;
+	atomic_inc(&nmi_active);
+	__acpi_nmi_enable(NULL);
+}
+
+static void enable_ioapic_nmi_watchdog(void)
+{
+	on_each_cpu(enable_ioapic_nmi_watchdog_single, NULL, 0, 1);
+	touch_nmi_watchdog();
+}
+
+static void disable_ioapic_nmi_watchdog(void)
+{
+	on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
+}
+
 static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
 {
 	unsigned char reason = get_nmi_reason();
@@ -431,6 +451,11 @@ int proc_nmi_enabled(struct ctl_table *t
 			enable_lapic_nmi_watchdog();
 		else
 			disable_lapic_nmi_watchdog();
+	} else if (nmi_watchdog == NMI_IO_APIC) {
+		if (nmi_watchdog_enabled)
+			enable_ioapic_nmi_watchdog();
+		else
+			disable_ioapic_nmi_watchdog();
 	} else {
 		printk( KERN_WARNING
 			"NMI watchdog doesn't know what hardware to touch\n");
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.