diff options
author | Don Zickus <dzickus@redhat.com> | 2006-09-26 04:52:27 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:27 -0400 |
commit | e33e89ab1a8d295de0500b697f4f31c3ceee9aa2 (patch) | |
tree | 51a7955a1a67f65169278a97d3d54305cb18e8ae | |
parent | 407984f1af259b31957c7c05075a454a751bb801 (diff) |
[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>
-rw-r--r-- | Documentation/filesystems/proc.txt | 14 | ||||
-rw-r--r-- | arch/i386/kernel/nmi.c | 21 | ||||
-rw-r--r-- | arch/x86_64/kernel/nmi.c | 21 |
3 files changed, 17 insertions, 39 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 99902ae6804e..7db71d6fba82 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -1124,11 +1124,15 @@ debugging information is displayed on console. | |||
1124 | NMI switch that most IA32 servers have fires unknown NMI up, for example. | 1124 | NMI switch that most IA32 servers have fires unknown NMI up, for example. |
1125 | If a system hangs up, try pressing the NMI switch. | 1125 | If a system hangs up, try pressing the NMI switch. |
1126 | 1126 | ||
1127 | [NOTE] | 1127 | nmi_watchdog |
1128 | This function and oprofile share a NMI callback. Therefore this function | 1128 | ------------ |
1129 | cannot be enabled when oprofile is activated. | 1129 | |
1130 | And NMI watchdog will be disabled when the value in this file is set to | 1130 | Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero |
1131 | non-zero. | 1131 | the NMI watchdog is enabled and will continuously test all online cpus to |
1132 | determine whether or not they are still functioning properly. | ||
1133 | |||
1134 | Because the NMI watchdog shares registers with oprofile, by disabling the NMI | ||
1135 | watchdog, oprofile may have more registers to utilize. | ||
1132 | 1136 | ||
1133 | 1137 | ||
1134 | 2.4 /proc/sys/vm - The virtual memory subsystem | 1138 | 2.4 /proc/sys/vm - The virtual memory subsystem |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 28065d0b71a9..6241e4448cab 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -847,7 +847,7 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) | |||
847 | } | 847 | } |
848 | 848 | ||
849 | /* | 849 | /* |
850 | * proc handler for /proc/sys/kernel/nmi_watchdog | 850 | * proc handler for /proc/sys/kernel/nmi |
851 | */ | 851 | */ |
852 | int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, | 852 | int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, |
853 | void __user *buffer, size_t *length, loff_t *ppos) | 853 | 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 | return 0; | 861 | return 0; |
862 | 862 | ||
863 | if (atomic_read(&nmi_active) < 0) { | 863 | if (atomic_read(&nmi_active) < 0) { |
864 | printk(KERN_WARNING "NMI watchdog is permanently disabled\n"); | 864 | printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); |
865 | return -EINVAL; | 865 | return -EIO; |
866 | } | 866 | } |
867 | 867 | ||
868 | if (nmi_watchdog == NMI_DEFAULT) { | 868 | if (nmi_watchdog == NMI_DEFAULT) { |
@@ -872,24 +872,11 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, | |||
872 | nmi_watchdog = NMI_IO_APIC; | 872 | nmi_watchdog = NMI_IO_APIC; |
873 | } | 873 | } |
874 | 874 | ||
875 | if (nmi_watchdog == NMI_LOCAL_APIC) | 875 | if (nmi_watchdog == NMI_LOCAL_APIC) { |
876 | { | ||
877 | if (nmi_watchdog_enabled) | 876 | if (nmi_watchdog_enabled) |
878 | enable_lapic_nmi_watchdog(); | 877 | enable_lapic_nmi_watchdog(); |
879 | else | 878 | else |
880 | disable_lapic_nmi_watchdog(); | 879 | disable_lapic_nmi_watchdog(); |
881 | } else if (nmi_watchdog == NMI_IO_APIC) { | ||
882 | /* FIXME | ||
883 | * for some reason these functions don't work | ||
884 | */ | ||
885 | printk("Can not enable/disable NMI on IO APIC\n"); | ||
886 | return -EINVAL; | ||
887 | #if 0 | ||
888 | if (nmi_watchdog_enabled) | ||
889 | enable_timer_nmi_watchdog(); | ||
890 | else | ||
891 | disable_timer_nmi_watchdog(); | ||
892 | #endif | ||
893 | } else { | 880 | } else { |
894 | printk( KERN_WARNING | 881 | printk( KERN_WARNING |
895 | "NMI watchdog doesn't know what hardware to touch\n"); | 882 | "NMI watchdog doesn't know what hardware to touch\n"); |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 3a17411a9a19..dd57410dad51 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -167,7 +167,7 @@ static __cpuinit inline int nmi_known_cpu(void) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | /* Run after command line and cpu_init init, but before all other checks */ | 169 | /* Run after command line and cpu_init init, but before all other checks */ |
170 | void __cpuinit nmi_watchdog_default(void) | 170 | void nmi_watchdog_default(void) |
171 | { | 171 | { |
172 | if (nmi_watchdog != NMI_DEFAULT) | 172 | if (nmi_watchdog != NMI_DEFAULT) |
173 | return; | 173 | return; |
@@ -766,32 +766,19 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, | |||
766 | 766 | ||
767 | if (atomic_read(&nmi_active) < 0) { | 767 | if (atomic_read(&nmi_active) < 0) { |
768 | printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); | 768 | printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); |
769 | return -EINVAL; | 769 | return -EIO; |
770 | } | 770 | } |
771 | 771 | ||
772 | /* if nmi_watchdog is not set yet, then set it */ | 772 | /* if nmi_watchdog is not set yet, then set it */ |
773 | nmi_watchdog_default(); | 773 | nmi_watchdog_default(); |
774 | 774 | ||
775 | if (nmi_watchdog == NMI_LOCAL_APIC) | 775 | if (nmi_watchdog == NMI_LOCAL_APIC) { |
776 | { | ||
777 | if (nmi_watchdog_enabled) | 776 | if (nmi_watchdog_enabled) |
778 | enable_lapic_nmi_watchdog(); | 777 | enable_lapic_nmi_watchdog(); |
779 | else | 778 | else |
780 | disable_lapic_nmi_watchdog(); | 779 | disable_lapic_nmi_watchdog(); |
781 | } else if (nmi_watchdog == NMI_IO_APIC) { | ||
782 | /* FIXME | ||
783 | * for some reason these functions don't work | ||
784 | */ | ||
785 | printk("Can not enable/disable NMI on IO APIC\n"); | ||
786 | return -EIO; | ||
787 | #if 0 | ||
788 | if (nmi_watchdog_enabled) | ||
789 | enable_timer_nmi_watchdog(); | ||
790 | else | ||
791 | disable_timer_nmi_watchdog(); | ||
792 | #endif | ||
793 | } else { | 780 | } else { |
794 | printk(KERN_WARNING | 781 | printk( KERN_WARNING |
795 | "NMI watchdog doesn't know what hardware to touch\n"); | 782 | "NMI watchdog doesn't know what hardware to touch\n"); |
796 | return -EIO; | 783 | return -EIO; |
797 | } | 784 | } |