2012-06-06 16:02:44

by Arun Sharma

[permalink] [raw]
Subject: [tip:perf/core] perf/x86: Allow multiple stacks

Commit-ID: 302fa4b58ac754a6da13f4f5546f710fecc3b945
Gitweb: http://git.kernel.org/tip/302fa4b58ac754a6da13f4f5546f710fecc3b945
Author: Arun Sharma <[email protected]>
AuthorDate: Fri, 20 Apr 2012 15:41:33 -0700
Committer: Ingo Molnar <[email protected]>
CommitDate: Wed, 6 Jun 2012 17:07:58 +0200

perf/x86: Allow multiple stacks

Without this patch, applications with two different stack
regions (eg: native stack vs JIT stack) get truncated
callchains even when RBP chaining is present. GDB shows proper
stack traces and the frame pointer chaining is intact.

This patch disables the (fp < RSP) check, hoping that other checks
in the code save the day for us. In our limited testing, this
didn't seem to break anything.

In the long term, we could potentially have userspace advise
the kernel on the range of valid stack addresses, so we don't
spend a lot of time unwinding from bogus addresses.

Signed-off-by: Arun Sharma <[email protected]>
CC: Arnaldo Carvalho de Melo <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Tom Zanussi <[email protected]>
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
---
arch/x86/kernel/cpu/perf_event.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index cb60838..e78bc25 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -1781,9 +1781,6 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
if (bytes != sizeof(frame))
break;

- if (fp < compat_ptr(regs->sp))
- break;
-
perf_callchain_store(entry, frame.return_address);
fp = compat_ptr(frame.next_frame);
}
@@ -1827,9 +1824,6 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
if (bytes != sizeof(frame))
break;

- if ((unsigned long)fp < regs->sp)
- break;
-
perf_callchain_store(entry, frame.return_address);
fp = frame.next_frame;
}