On arm64, automatically record all the registers if the frame pointer mode is on. They will be used to do a dwarf unwind to find the caller of the leaf frame if the frame pointer was omitted.
Signed-off-by: Alexandre Truong <[email protected]> Cc: John Garry <[email protected]> Cc: Will Deacon <[email protected]> Cc: Mathieu Poirier <[email protected]> Cc: Leo Yan <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Kemeng Shi <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Kan Liang <[email protected]> Cc: Jin Yao <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Suzuki K Poulose <[email protected]> Cc: Al Grant <[email protected]> Cc: James Clark <[email protected]> Cc: Wilco Dijkstra <[email protected]> --- tools/perf/arch/arm64/util/machine.c | 5 +++++ tools/perf/builtin-record.c | 7 +++++++ tools/perf/util/callchain.h | 2 ++ 3 files changed, 14 insertions(+) diff --git a/tools/perf/arch/arm64/util/machine.c b/tools/perf/arch/arm64/util/machine.c index d41b27e781d3..6ba1d356a20c 100644 --- a/tools/perf/arch/arm64/util/machine.c +++ b/tools/perf/arch/arm64/util/machine.c @@ -25,3 +25,8 @@ void arch__symbols__fixup_end(struct symbol *p, struct symbol *c) p->end = c->start; pr_debug4("%s sym:%s end:%#lx\n", __func__, p->name, p->end); } + +void arch__add_leaf_frame_record_opts(struct record_opts *opts) +{ + opts->sample_user_regs = arch__user_reg_mask(); +} diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 7bb10e9863bd..a5161f54b838 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -2243,6 +2243,10 @@ static int record__parse_mmap_pages(const struct option *opt, return ret; } +void __weak arch__add_leaf_frame_record_opts(struct record_opts *opts __maybe_unused) +{ +} + static int parse_control_option(const struct option *opt, const char *str, int unset __maybe_unused) @@ -2810,6 +2814,9 @@ int cmd_record(int argc, const char **argv) /* Enable ignoring missing threads when -u/-p option is defined. */ rec->opts.ignore_missing_thread = rec->opts.target.uid != UINT_MAX || rec->opts.target.pid; + if (callchain_param.enabled && callchain_param.record_mode == CALLCHAIN_FP) + arch__add_leaf_frame_record_opts(&rec->opts); + err = -ENOMEM; if (evlist__create_maps(rec->evlist, &rec->opts.target) < 0) usage_with_options(record_usage, record_options); diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 5824134f983b..77fba053c677 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -280,6 +280,8 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, } #endif +void arch__add_leaf_frame_record_opts(struct record_opts *opts); + char *callchain_list__sym_name(struct callchain_list *cl, char *bf, size_t bfsize, bool show_dso); char *callchain_node__scnprintf_value(struct callchain_node *node, -- 2.23.0

