diff options
Diffstat (limited to 'arch/x86/kernel/cpu/perf_counter.c')
-rw-r--r-- | arch/x86/kernel/cpu/perf_counter.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d4cf4ce19aac..36c3dc7b8991 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
@@ -1561,6 +1561,7 @@ void callchain_store(struct perf_callchain_entry *entry, u64 ip) | |||
1561 | 1561 | ||
1562 | static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); | 1562 | static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); |
1563 | static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); | 1563 | static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); |
1564 | static DEFINE_PER_CPU(int, in_nmi_frame); | ||
1564 | 1565 | ||
1565 | 1566 | ||
1566 | static void | 1567 | static void |
@@ -1576,7 +1577,9 @@ static void backtrace_warning(void *data, char *msg) | |||
1576 | 1577 | ||
1577 | static int backtrace_stack(void *data, char *name) | 1578 | static int backtrace_stack(void *data, char *name) |
1578 | { | 1579 | { |
1579 | /* Process all stacks: */ | 1580 | per_cpu(in_nmi_frame, smp_processor_id()) = |
1581 | x86_is_stack_id(NMI_STACK, name); | ||
1582 | |||
1580 | return 0; | 1583 | return 0; |
1581 | } | 1584 | } |
1582 | 1585 | ||
@@ -1584,6 +1587,9 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) | |||
1584 | { | 1587 | { |
1585 | struct perf_callchain_entry *entry = data; | 1588 | struct perf_callchain_entry *entry = data; |
1586 | 1589 | ||
1590 | if (per_cpu(in_nmi_frame, smp_processor_id())) | ||
1591 | return; | ||
1592 | |||
1587 | if (reliable) | 1593 | if (reliable) |
1588 | callchain_store(entry, addr); | 1594 | callchain_store(entry, addr); |
1589 | } | 1595 | } |