diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-08-05 02:45:05 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-08-05 02:45:05 -0400 |
| commit | 61be7fdec2f51b99570cd5dcc30c7848c8e56513 (patch) | |
| tree | 4a73ee635bc3e35dc54f75caddd26ffb6238bb5c | |
| parent | 12a81c8df13c60904febcafcf6b90ca1acb67122 (diff) | |
| parent | eb703f98191a505f78d0066712ad67d5dedc4c90 (diff) | |
Merge branch 'perf/nmi' into perf/core
Conflicts:
kernel/Makefile
Merge reason: Add the now complete topic, fix the conflict.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
| -rw-r--r-- | arch/Kconfig | 7 | ||||
| -rw-r--r-- | arch/x86/Kconfig | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/nmi.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/Makefile | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/hw_nmi.c | 107 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/nmi.c | 7 | ||||
| -rw-r--r-- | arch/x86/kernel/traps.c | 7 | ||||
| -rw-r--r-- | include/linux/nmi.h | 13 | ||||
| -rw-r--r-- | include/linux/sched.h | 12 | ||||
| -rw-r--r-- | kernel/Makefile | 2 | ||||
| -rw-r--r-- | kernel/softlockup.c | 293 | ||||
| -rw-r--r-- | kernel/sysctl.c | 55 | ||||
| -rw-r--r-- | kernel/timer.c | 1 | ||||
| -rw-r--r-- | kernel/watchdog.c | 567 | ||||
| -rw-r--r-- | lib/Kconfig.debug | 35 |
16 files changed, 770 insertions, 348 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 2b2407d9a6d0..c45a3548537a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1812,6 +1812,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 1812 | 1812 | ||
| 1813 | nousb [USB] Disable the USB subsystem | 1813 | nousb [USB] Disable the USB subsystem |
| 1814 | 1814 | ||
| 1815 | nowatchdog [KNL] Disable the lockup detector. | ||
| 1816 | |||
| 1815 | nowb [ARM] | 1817 | nowb [ARM] |
| 1816 | 1818 | ||
| 1817 | nox2apic [X86-64,APIC] Do not enable x2APIC mode. | 1819 | nox2apic [X86-64,APIC] Do not enable x2APIC mode. |
diff --git a/arch/Kconfig b/arch/Kconfig index acda512da2e2..4877a8c8ee16 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -151,4 +151,11 @@ config HAVE_MIXED_BREAKPOINTS_REGS | |||
| 151 | config HAVE_USER_RETURN_NOTIFIER | 151 | config HAVE_USER_RETURN_NOTIFIER |
| 152 | bool | 152 | bool |
| 153 | 153 | ||
| 154 | config HAVE_PERF_EVENTS_NMI | ||
| 155 | bool | ||
| 156 | help | ||
| 157 | System hardware can generate an NMI using the perf event | ||
| 158 | subsystem. Also has support for calculating CPU cycle events | ||
| 159 | to determine how many clock cycles in a given period. | ||
| 160 | |||
| 154 | source "kernel/gcov/Kconfig" | 161 | source "kernel/gcov/Kconfig" |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index dcb0593b4a66..6f77afa6bca9 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -55,6 +55,7 @@ config X86 | |||
| 55 | select HAVE_HW_BREAKPOINT | 55 | select HAVE_HW_BREAKPOINT |
| 56 | select HAVE_MIXED_BREAKPOINTS_REGS | 56 | select HAVE_MIXED_BREAKPOINTS_REGS |
| 57 | select PERF_EVENTS | 57 | select PERF_EVENTS |
| 58 | select HAVE_PERF_EVENTS_NMI | ||
| 58 | select ANON_INODES | 59 | select ANON_INODES |
| 59 | select HAVE_ARCH_KMEMCHECK | 60 | select HAVE_ARCH_KMEMCHECK |
| 60 | select HAVE_USER_RETURN_NOTIFIER | 61 | select HAVE_USER_RETURN_NOTIFIER |
diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index 93da9c3f3341..932f0f86b4b7 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h | |||
| @@ -17,7 +17,9 @@ int do_nmi_callback(struct pt_regs *regs, int cpu); | |||
| 17 | 17 | ||
| 18 | extern void die_nmi(char *str, struct pt_regs *regs, int do_panic); | 18 | extern void die_nmi(char *str, struct pt_regs *regs, int do_panic); |
| 19 | extern int check_nmi_watchdog(void); | 19 | extern int check_nmi_watchdog(void); |
| 20 | #if !defined(CONFIG_LOCKUP_DETECTOR) | ||
| 20 | extern int nmi_watchdog_enabled; | 21 | extern int nmi_watchdog_enabled; |
| 22 | #endif | ||
| 21 | extern int avail_to_resrv_perfctr_nmi_bit(unsigned int); | 23 | extern int avail_to_resrv_perfctr_nmi_bit(unsigned int); |
| 22 | extern int reserve_perfctr_nmi(unsigned int); | 24 | extern int reserve_perfctr_nmi(unsigned int); |
| 23 | extern void release_perfctr_nmi(unsigned int); | 25 | extern void release_perfctr_nmi(unsigned int); |
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index 565c1bfc507d..910f20b457c4 100644 --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile | |||
| @@ -2,7 +2,12 @@ | |||
| 2 | # Makefile for local APIC drivers and for the IO-APIC code | 2 | # Makefile for local APIC drivers and for the IO-APIC code |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o probe_$(BITS).o ipi.o nmi.o | 5 | obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o probe_$(BITS).o ipi.o |
| 6 | ifneq ($(CONFIG_HARDLOCKUP_DETECTOR),y) | ||
| 7 | obj-$(CONFIG_X86_LOCAL_APIC) += nmi.o | ||
| 8 | endif | ||
| 9 | obj-$(CONFIG_HARDLOCKUP_DETECTOR) += hw_nmi.o | ||
| 10 | |||
| 6 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o | 11 | obj-$(CONFIG_X86_IO_APIC) += io_apic.o |
| 7 | obj-$(CONFIG_SMP) += ipi.o | 12 | obj-$(CONFIG_SMP) += ipi.o |
| 8 | 13 | ||
diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c new file mode 100644 index 000000000000..cefd6942f0e9 --- /dev/null +++ b/arch/x86/kernel/apic/hw_nmi.c | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /* | ||
| 2 | * HW NMI watchdog support | ||
| 3 | * | ||
| 4 | * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc. | ||
| 5 | * | ||
| 6 | * Arch specific calls to support NMI watchdog | ||
| 7 | * | ||
| 8 | * Bits copied from original nmi.c file | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | #include <asm/apic.h> | ||
| 12 | |||
| 13 | #include <linux/cpumask.h> | ||
| 14 | #include <linux/kdebug.h> | ||
| 15 | #include <linux/notifier.h> | ||
| 16 | #include <linux/kprobes.h> | ||
| 17 | #include <linux/nmi.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | |||
| 20 | /* For reliability, we're prepared to waste bits here. */ | ||
| 21 | static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; | ||
| 22 | |||
| 23 | u64 hw_nmi_get_sample_period(void) | ||
| 24 | { | ||
| 25 | return (u64)(cpu_khz) * 1000 * 60; | ||
| 26 | } | ||
| 27 | |||
| 28 | #ifdef ARCH_HAS_NMI_WATCHDOG | ||
| 29 | void arch_trigger_all_cpu_backtrace(void) | ||
| 30 | { | ||
| 31 | int i; | ||
| 32 | |||
| 33 | cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); | ||
| 34 | |||
| 35 | printk(KERN_INFO "sending NMI to all CPUs:\n"); | ||
| 36 | apic->send_IPI_all(NMI_VECTOR); | ||
| 37 | |||
| 38 | /* Wait for up to 10 seconds for all CPUs to do the backtrace */ | ||
| 39 | for (i = 0; i < 10 * 1000; i++) { | ||
| 40 | if (cpumask_empty(to_cpumask(backtrace_mask))) | ||
| 41 | break; | ||
| 42 | mdelay(1); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | static int __kprobes | ||
| 47 | arch_trigger_all_cpu_backtrace_handler(struct notifier_block *self, | ||
| 48 | unsigned long cmd, void *__args) | ||
| 49 | { | ||
| 50 | struct die_args *args = __args; | ||
| 51 | struct pt_regs *regs; | ||
| 52 | int cpu = smp_processor_id(); | ||
| 53 | |||
| 54 | switch (cmd) { | ||
| 55 | case DIE_NMI: | ||
| 56 | case DIE_NMI_IPI: | ||
| 57 | break; | ||
| 58 | |||
| 59 | default: | ||
| 60 | return NOTIFY_DONE; | ||
| 61 | } | ||
| 62 | |||
| 63 | regs = args->regs; | ||
| 64 | |||
| 65 | if (cpumask_test_cpu(cpu, to_cpumask(backtrace_mask))) { | ||
| 66 | static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED; | ||
| 67 | |||
| 68 | arch_spin_lock(&lock); | ||
| 69 | printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu); | ||
| 70 | show_regs(regs); | ||
| 71 | dump_stack(); | ||
| 72 | arch_spin_unlock(&lock); | ||
| 73 | cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); | ||
| 74 | return NOTIFY_STOP; | ||
| 75 | } | ||
| 76 | |||
| 77 | return NOTIFY_DONE; | ||
| 78 | } | ||
| 79 | |||
| 80 | static __read_mostly struct notifier_block backtrace_notifier = { | ||
| 81 | .notifier_call = arch_trigger_all_cpu_backtrace_handler, | ||
| 82 | .next = NULL, | ||
| 83 | .priority = 1 | ||
| 84 | }; | ||
| 85 | |||
| 86 | static int __init register_trigger_all_cpu_backtrace(void) | ||
| 87 | { | ||
| 88 | register_die_notifier(&backtrace_notifier); | ||
| 89 | return 0; | ||
| 90 | } | ||
| 91 | early_initcall(register_trigger_all_cpu_backtrace); | ||
| 92 | #endif | ||
| 93 | |||
| 94 | /* STUB calls to mimic old nmi_watchdog behaviour */ | ||
| 95 | #if defined(CONFIG_X86_LOCAL_APIC) | ||
| 96 | unsigned int nmi_watchdog = NMI_NONE; | ||
| 97 | EXPORT_SYMBOL(nmi_watchdog); | ||
| 98 | void acpi_nmi_enable(void) { return; } | ||
| 99 | void acpi_nmi_disable(void) { return; } | ||
