From: Don Zickus 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 Cc: Andi Kleen Signed-off-by: Andrew Morton --- Documentation/filesystems/proc.txt | 14 +++++++++----- arch/i386/kernel/nmi.c | 21 ++++----------------- arch/x86_64/kernel/nmi.c | 21 ++++----------------- include/linux/sysctl.h | 5 ++--- kernel/sysctl.c | 2 +- asm-i386/nmi.h | 0 asm-x86_64/nmi.h | 0 7 files changed, 20 insertions(+), 43 deletions(-) diff -puN arch/i386/kernel/nmi.c~add-abilty-to-enable-disable-nmi-watchdog-from-procfs arch/i386/kernel/nmi.c --- devel/arch/i386/kernel/nmi.c~add-abilty-to-enable-disable-nmi-watchdog-from-procfs 2006-05-13 08:39:03.000000000 -0700 +++ devel-akpm/arch/i386/kernel/nmi.c 2006-05-13 08:39:03.000000000 -0700 @@ -846,7 +846,7 @@ static int unknown_nmi_panic_callback(st } /* - * 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, void __user *buffer, size_t *length, loff_t *ppos) @@ -860,8 +860,8 @@ int proc_nmi_enabled(struct ctl_table *t return 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) { @@ -871,24 +871,11 @@ int proc_nmi_enabled(struct ctl_table *t nmi_watchdog = NMI_IO_APIC; } - if (nmi_watchdog == NMI_LOCAL_APIC) - { + if (nmi_watchdog == NMI_LOCAL_APIC) { if (nmi_watchdog_enabled) enable_lapic_nmi_watchdog(); else 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 { printk( KERN_WARNING "NMI watchdog doesn't know what hardware to touch\n"); diff -puN arch/x86_64/kernel/nmi.c~add-abilty-to-enable-disable-nmi-watchdog-from-procfs arch/x86_64/kernel/nmi.c --- devel/arch/x86_64/kernel/nmi.c~add-abilty-to-enable-disable-nmi-watchdog-from-procfs 2006-05-13 08:39:03.000000000 -0700 +++ devel-akpm/arch/x86_64/kernel/nmi.c 2006-05-13 08:39:03.000000000 -0700 @@ -168,7 +168,7 @@ static __cpuinit inline int nmi_known_cp } /* 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) return; @@ -767,32 +767,19 @@ int proc_nmi_enabled(struct ctl_table *t if (atomic_read(&nmi_active) < 0) { printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); - return -EINVAL; + return -EIO; } /* if nmi_watchdog is not set yet, then set it */ nmi_watchdog_default(); - if (nmi_watchdog == NMI_LOCAL_APIC) - { + if (nmi_watchdog == NMI_LOCAL_APIC) { if (nmi_watchdog_enabled) enable_lapic_nmi_watchdog(); else 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 { - printk(KERN_WARNING + printk( KERN_WARNING "NMI watchdog doesn't know what hardware to touch\n"); return -EIO; } diff -puN Documentation/filesystems/proc.txt~add-abilty-to-enable-disable-nmi-watchdog-from-procfs Documentation/filesystems/proc.txt --- devel/Documentation/filesystems/proc.txt~add-abilty-to-enable-disable-nmi-watchdog-from-procfs 2006-05-13 08:39:03.000000000 -0700 +++ devel-akpm/Documentation/filesystems/proc.txt 2006-05-13 08:39:03.000000000 -0700 @@ -1124,11 +1124,15 @@ debugging information is displayed on co NMI switch that most IA32 servers have fires unknown NMI up, for example. 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 diff -puN include/asm-i386/nmi.h~add-abilty-to-enable-disable-nmi-watchdog-from-procfs include/asm-i386/nmi.h diff -puN include/asm-x86_64/nmi.h~add-abilty-to-enable-disable-nmi-watchdog-from-procfs include/asm-x86_64/nmi.h diff -puN include/linux/sysctl.h~add-abilty-to-enable-disable-nmi-watchdog-from-procfs include/linux/sysctl.h --- devel/include/linux/sysctl.h~add-abilty-to-enable-disable-nmi-watchdog-from-procfs 2006-05-13 08:39:03.000000000 -0700 +++ devel-akpm/include/linux/sysctl.h 2006-05-13 08:39:03.000000000 -0700 @@ -148,12 +148,11 @@ enum KERN_SPIN_RETRY=70, /* int: number of spinlock retries */ KERN_ACPI_VIDEO_FLAGS=71, /* int: flags for setting up video after ACPI sleep */ KERN_IA64_UNALIGNED=72, /* int: ia64 unaligned userland trap enable */ - KERN_COMPAT_LOG=73, /* int: print compat layer messages */ - KERN_NMI_WATCHDOG=74, /* int: enable/disable nmi watchdog */ + KERN_COMPAT_LOG=73, /* int: print compat layer messages */ + KERN_NMI_ENABLED=74, /* int: enable/disable nmi watchdog */ }; - /* CTL_VM names: */ enum { diff -puN kernel/sysctl.c~add-abilty-to-enable-disable-nmi-watchdog-from-procfs kernel/sysctl.c --- devel/kernel/sysctl.c~add-abilty-to-enable-disable-nmi-watchdog-from-procfs 2006-05-13 08:39:03.000000000 -0700 +++ devel-akpm/kernel/sysctl.c 2006-05-13 08:39:03.000000000 -0700 @@ -638,7 +638,7 @@ static ctl_table kern_table[] = { .proc_handler = &proc_dointvec, }, { - .ctl_name = KERN_NMI_WATCHDOG, + .ctl_name = KERN_NMI_ENABLED, .procname = "nmi_watchdog", .data = &nmi_watchdog_enabled, .maxlen = sizeof (int), _