Patchwork [2/2] MIPS: Implement perf_callchain_user using unwind_user_frame

login
register
mail settings
Submitter Holger Freyther
Date 2011-08-11 12:08:06
Message ID <1313022966-28152-3-git-send-email-zecke@selfish.org>
Download mbox | patch
Permalink /patch/2699/
State New
Headers show

Comments

Holger Freyther - 2011-08-11 12:08:06
Implement perf_callchain_user using the unwind_user_frame
method, allow up to PAGE_SIZE / 4 instructions to be checked.

Signed-off-by: Holger Freyther <holger@moiji-mobile.com>
---
 arch/mips/kernel/perf_event.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

Patch

diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c
index 0aee944..7ea4d3c 100644
--- a/arch/mips/kernel/perf_event.c
+++ b/arch/mips/kernel/perf_event.c
@@ -540,6 +540,20 @@  handle_associated_event(struct cpu_hw_events *cpuc,
 void perf_callchain_user(struct perf_callchain_entry *entry,
 		    struct pt_regs *regs)
 {
+	struct user_stackframe frame = { .sp = regs->regs[29],
+				    .pc = regs->cp0_epc,
+				    .ra = regs->regs[31] };
+	const unsigned long low_addr = ALIGN(frame.sp, THREAD_SIZE);
+	const unsigned int max_instr_check = PAGE_SIZE / 4;
+	const unsigned long high_addr = low_addr + THREAD_SIZE;
+
+
+	while (entry->nr < PERF_MAX_STACK_DEPTH &&
+			!unwind_user_frame(&frame, max_instr_check)) {
+		perf_callchain_store(entry, frame.ra);
+		if (frame.sp < low_addr || frame.sp > high_addr)
+			break;
+	}
 }
 
 static void save_raw_perf_callchain(struct perf_callchain_entry *entry,