linux-mips
[Top] [All Lists]

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

To: linux-mips@linux-mips.org
Subject: [PATCH 2/2] MIPS: Implement perf_callchain_user using unwind_user_frame
From: Holger Hans Peter Freyther <zecke@selfish.org>
Date: Thu, 11 Aug 2011 02:36:06 +0200
Cc: Holger Hans Peter Freyther <zecke@selfish.org>, Holger Freyther <holger@moiji-mobile.com>
In-reply-to: <1313022966-28152-1-git-send-email-zecke@selfish.org>
References: <1313022966-28152-1-git-send-email-zecke@selfish.org>
Sender: linux-mips-bounce@linux-mips.org
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(-)

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,
-- 
1.7.4.1


<Prev in Thread] Current Thread [Next in Thread>