Skip to content

Commit ed876d3

Browse files
madvenka786ctmarinas
authored andcommitted
arm64: Make perf_callchain_kernel() use arch_stack_walk()
To enable RELIABLE_STACKTRACE and LIVEPATCH on arm64, we need to substantially rework arm64's unwinding code. As part of this, we want to minimize the set of unwind interfaces we expose, and avoid open-coding of unwind logic outside of stacktrace.c. Currently perf_callchain_kernel() walks the stack of an interrupted context by calling start_backtrace() with the context's PC and FP, and iterating unwind steps using walk_stackframe(). This is functionally equivalent to calling arch_stack_walk() with the interrupted context's pt_regs, which will start with the PC and FP from the regs. Make perf_callchain_kernel() use arch_stack_walk(). This simplifies perf_callchain_kernel(), and in future will alow us to make walk_stackframe() private to stacktrace.c. At the same time, we update the callchain_trace() callback to check the return value of perf_callchain_store(), which indicates whether there is space for any further entries. When a non-zero value is returned, further calls will be ignored, and are redundant, so we can stop the unwind at this point. We also remove the stale and confusing comment for callchain_trace. There should be no functional change as a result of this patch. Signed-off-by: Madhavan T. Venkataraman <[email protected]> Tested-by: Mark Rutland <[email protected]> Reviewed-by: Mark Brown <[email protected]> Reviewed-by: Mark Rutland <[email protected]> [Mark: elaborate commit message, remove comment, fix includes] Signed-off-by: Mark Rutland <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 86bcbaf commit ed876d3

File tree

1 file changed

+3
-12
lines changed

1 file changed

+3
-12
lines changed

arch/arm64/kernel/perf_callchain.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
* Copyright (C) 2015 ARM Limited
66
*/
77
#include <linux/perf_event.h>
8+
#include <linux/stacktrace.h>
89
#include <linux/uaccess.h>
910

1011
#include <asm/pointer_auth.h>
11-
#include <asm/stacktrace.h>
1212

1313
struct frame_tail {
1414
struct frame_tail __user *fp;
@@ -132,30 +132,21 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
132132
}
133133
}
134134

135-
/*
136-
* Gets called by walk_stackframe() for every stackframe. This will be called
137-
* whist unwinding the stackframe and is like a subroutine return so we use
138-
* the PC.
139-
*/
140135
static bool callchain_trace(void *data, unsigned long pc)
141136
{
142137
struct perf_callchain_entry_ctx *entry = data;
143-
perf_callchain_store(entry, pc);
144-
return true;
138+
return perf_callchain_store(entry, pc) == 0;
145139
}
146140

147141
void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
148142
struct pt_regs *regs)
149143
{
150-
struct stackframe frame;
151-
152144
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
153145
/* We don't support guest os callchain now */
154146
return;
155147
}
156148

157-
start_backtrace(&frame, regs->regs[29], regs->pc);
158-
walk_stackframe(current, &frame, callchain_trace, entry);
149+
arch_stack_walk(callchain_trace, entry, current, regs);
159150
}
160151

161152
unsigned long perf_instruction_pointer(struct pt_regs *regs)

0 commit comments

Comments
 (0)