فهرست منبع

[PATCH] x86: Add abilty to enable/disable nmi watchdog from procfs (update)

Adds a new /proc/sys/kernel/nmi_watchdog call that will enable/disable the
nmi watchdog.

By entering a non-zero value here, a user can enable the nmi watchdog to
monitor the online cpus in the system.  By entering a zero value here, a
user can disable the nmi watchdog and free up a performance counter which
could then be utilized by the oprofile subsystem, otherwise oprofile may be
short a counter when in use.

Signed-off-by: Don Zickus <dzickus@redhat.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Don Zickus 19 سال پیش
والد
کامیت
e33e89ab1a
3فایلهای تغییر یافته به همراه17 افزوده شده و 39 حذف شده
  1. 9 5
      Documentation/filesystems/proc.txt
  2. 4 17
      arch/i386/kernel/nmi.c
  3. 4 17
      arch/x86_64/kernel/nmi.c

+ 9 - 5
Documentation/filesystems/proc.txt

@@ -1124,11 +1124,15 @@ debugging information is displayed on console.
 NMI switch that most IA32 servers have fires unknown NMI up, for example.
 NMI switch that most IA32 servers have fires unknown NMI up, for example.
 If a system hangs up, try pressing the NMI switch.
 If a system hangs up, try pressing the NMI switch.
 
 
-[NOTE]
-   This function and oprofile share a NMI callback. Therefore this function
-   cannot be enabled when oprofile is activated.
-   And NMI watchdog will be disabled when the value in this file is set to
-   non-zero.
+nmi_watchdog
+------------
+
+Enables/Disables the NMI watchdog on x86 systems.  When the value is non-zero
+the NMI watchdog is enabled and will continuously test all online cpus to
+determine whether or not they are still functioning properly.
+
+Because the NMI watchdog shares registers with oprofile, by disabling the NMI
+watchdog, oprofile may have more registers to utilize.
 
 
 
 
 2.4 /proc/sys/vm - The virtual memory subsystem
 2.4 /proc/sys/vm - The virtual memory subsystem

+ 4 - 17
arch/i386/kernel/nmi.c

@@ -847,7 +847,7 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
 }
 }
 
 
 /*
 /*
- * proc handler for /proc/sys/kernel/nmi_watchdog
+ * proc handler for /proc/sys/kernel/nmi
  */
  */
 int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
 int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
 			void __user *buffer, size_t *length, loff_t *ppos)
 			void __user *buffer, size_t *length, loff_t *ppos)
@@ -861,8 +861,8 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
 		return 0;
 		return 0;
 
 
 	if (atomic_read(&nmi_active) < 0) {
 	if (atomic_read(&nmi_active) < 0) {
-		printk(KERN_WARNING "NMI watchdog is permanently disabled\n");
-		return -EINVAL;
+		printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
+		return -EIO;
 	}
 	}
 
 
 	if (nmi_watchdog == NMI_DEFAULT) {
 	if (nmi_watchdog == NMI_DEFAULT) {
@@ -872,24 +872,11 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
 			nmi_watchdog = NMI_IO_APIC;
 			nmi_watchdog = NMI_IO_APIC;
 	}
 	}
 
 
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-	{
+	if (nmi_watchdog == NMI_LOCAL_APIC) {
 		if (nmi_watchdog_enabled)
 		if (nmi_watchdog_enabled)
 			enable_lapic_nmi_watchdog();
 			enable_lapic_nmi_watchdog();
 		else
 		else
 			disable_lapic_nmi_watchdog();
 			disable_lapic_nmi_watchdog();
-	} else if (nmi_watchdog == NMI_IO_APIC) {
-		/* FIXME
-		 * for some reason these functions don't work
-		 */
-		printk("Can not enable/disable NMI on IO APIC\n");
-		return -EINVAL;
-#if 0
-		if (nmi_watchdog_enabled)
-			enable_timer_nmi_watchdog();
-		else
-			disable_timer_nmi_watchdog();
-#endif
 	} else {
 	} else {
 		printk( KERN_WARNING
 		printk( KERN_WARNING
 			"NMI watchdog doesn't know what hardware to touch\n");
 			"NMI watchdog doesn't know what hardware to touch\n");

+ 4 - 17
arch/x86_64/kernel/nmi.c

@@ -167,7 +167,7 @@ static __cpuinit inline int nmi_known_cpu(void)
 }
 }
 
 
 /* Run after command line and cpu_init init, but before all other checks */
 /* Run after command line and cpu_init init, but before all other checks */
-void __cpuinit nmi_watchdog_default(void)
+void nmi_watchdog_default(void)
 {
 {
 	if (nmi_watchdog != NMI_DEFAULT)
 	if (nmi_watchdog != NMI_DEFAULT)
 		return;
 		return;
@@ -766,32 +766,19 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
 
 
 	if (atomic_read(&nmi_active) < 0) {
 	if (atomic_read(&nmi_active) < 0) {
 		printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
 		printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
-		return -EINVAL;
+		return -EIO;
 	}
 	}
 
 
 	/* if nmi_watchdog is not set yet, then set it */
 	/* if nmi_watchdog is not set yet, then set it */
 	nmi_watchdog_default();
 	nmi_watchdog_default();
 
 
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-	{
+	if (nmi_watchdog == NMI_LOCAL_APIC) {
 		if (nmi_watchdog_enabled)
 		if (nmi_watchdog_enabled)
 			enable_lapic_nmi_watchdog();
 			enable_lapic_nmi_watchdog();
 		else
 		else
 			disable_lapic_nmi_watchdog();
 			disable_lapic_nmi_watchdog();
-	} else if (nmi_watchdog == NMI_IO_APIC) {
-		/* FIXME
-		 * for some reason these functions don't work
-		 */
-		printk("Can not enable/disable NMI on IO APIC\n");
-		return -EIO;
-#if 0
-		if (nmi_watchdog_enabled)
-			enable_timer_nmi_watchdog();
-		else
-			disable_timer_nmi_watchdog();
-#endif
 	} else {
 	} else {
-		printk(KERN_WARNING
+		printk( KERN_WARNING
 			"NMI watchdog doesn't know what hardware to touch\n");
 			"NMI watchdog doesn't know what hardware to touch\n");
 		return -EIO;
 		return -EIO;
 	}
 	}