Commit e33e89ab authored by Don Zickus's avatar Don Zickus Committed by Andi Kleen

[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: default avatarDon Zickus <dzickus@redhat.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
parent 407984f1
...@@ -1124,11 +1124,15 @@ debugging information is displayed on console. ...@@ -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] nmi_watchdog
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 Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero
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
......
...@@ -847,7 +847,7 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) ...@@ -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, ...@@ -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"); printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
return -EINVAL; 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, ...@@ -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");
......
...@@ -167,7 +167,7 @@ static __cpuinit inline int nmi_known_cpu(void) ...@@ -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, ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment