perf events, x86/stacktrace: Make stack walking optional
The current print_context_stack helper that does the stack walking job is good for usual stacktraces as it walks through all the stack and reports even addresses that look unreliable, which is nice when we don't have frame pointers for example. But we have users like perf that only require reliable stacktraces, and those may want a more adapted stack walker, so lets make this function a callback in stacktrace_ops that users can tune for their needs. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1261024834-5336-1-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:

committed by
Ingo Molnar

parent
5b74ed4729
commit
61c1917f47
@@ -2336,6 +2336,7 @@ static const struct stacktrace_ops backtrace_ops = {
|
||||
.warning_symbol = backtrace_warning_symbol,
|
||||
.stack = backtrace_stack,
|
||||
.address = backtrace_address,
|
||||
.walk_stack = print_context_stack,
|
||||
};
|
||||
|
||||
#include "../dumpstack.h"
|
||||
|
@@ -141,10 +141,11 @@ static void print_trace_address(void *data, unsigned long addr, int reliable)
|
||||
}
|
||||
|
||||
static const struct stacktrace_ops print_trace_ops = {
|
||||
.warning = print_trace_warning,
|
||||
.warning_symbol = print_trace_warning_symbol,
|
||||
.stack = print_trace_stack,
|
||||
.address = print_trace_address,
|
||||
.warning = print_trace_warning,
|
||||
.warning_symbol = print_trace_warning_symbol,
|
||||
.stack = print_trace_stack,
|
||||
.address = print_trace_address,
|
||||
.walk_stack = print_context_stack,
|
||||
};
|
||||
|
||||
void
|
||||
|
@@ -14,12 +14,6 @@
|
||||
#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
|
||||
#endif
|
||||
|
||||
extern unsigned long
|
||||
print_context_stack(struct thread_info *tinfo,
|
||||
unsigned long *stack, unsigned long bp,
|
||||
const struct stacktrace_ops *ops, void *data,
|
||||
unsigned long *end, int *graph);
|
||||
|
||||
extern void
|
||||
show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
||||
unsigned long *stack, unsigned long bp, char *log_lvl);
|
||||
|
@@ -58,7 +58,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
||||
|
||||
context = (struct thread_info *)
|
||||
((unsigned long)stack & (~(THREAD_SIZE - 1)));
|
||||
bp = print_context_stack(context, stack, bp, ops, data, NULL, &graph);
|
||||
bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
|
||||
|
||||
stack = (unsigned long *)context->previous_esp;
|
||||
if (!stack)
|
||||
|
@@ -188,8 +188,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
||||
if (ops->stack(data, id) < 0)
|
||||
break;
|
||||
|
||||
bp = print_context_stack(tinfo, stack, bp, ops,
|
||||
data, estack_end, &graph);
|
||||
bp = ops->walk_stack(tinfo, stack, bp, ops,
|
||||
data, estack_end, &graph);
|
||||
ops->stack(data, "<EOE>");
|
||||
/*
|
||||
* We link to the next stack via the
|
||||
|
@@ -53,17 +53,19 @@ save_stack_address_nosched(void *data, unsigned long addr, int reliable)
|
||||
}
|
||||
|
||||
static const struct stacktrace_ops save_stack_ops = {
|
||||
.warning = save_stack_warning,
|
||||
.warning_symbol = save_stack_warning_symbol,
|
||||
.stack = save_stack_stack,
|
||||
.address = save_stack_address,
|
||||
.warning = save_stack_warning,
|
||||
.warning_symbol = save_stack_warning_symbol,
|
||||
.stack = save_stack_stack,
|
||||
.address = save_stack_address,
|
||||
.walk_stack = print_context_stack,
|
||||
};
|
||||
|
||||
static const struct stacktrace_ops save_stack_ops_nosched = {
|
||||
.warning = save_stack_warning,
|
||||
.warning_symbol = save_stack_warning_symbol,
|
||||
.stack = save_stack_stack,
|
||||
.address = save_stack_address_nosched,
|
||||
.warning = save_stack_warning,
|
||||
.warning_symbol = save_stack_warning_symbol,
|
||||
.stack = save_stack_stack,
|
||||
.address = save_stack_address_nosched,
|
||||
.walk_stack = print_context_stack,
|
||||
};
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user