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@xxxxxxxxxxxxxxxx> --- 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