Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf callchain: Enable dwarf_callchain_users on arm64

Enable dwarf_callchain_users on arm64 which will be needed to do a
DWARF unwind in order to get the caller of the leaf frame.

Reviewed-by: James Clark <james.clark@arm.com>
Signed-off-by: Alexandre Truong <alexandre.truong@arm.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Link: https://lore.kernel.org/r/20211217154521.80603-5-german.gomez@arm.com
Signed-off-by: German Gomez <german.gomez@arm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Alexandre Truong and committed by
Arnaldo Carvalho de Melo
aa8db3e4 ab236921

+18 -6
+2 -2
tools/perf/builtin-report.c
··· 410 410 } 411 411 } 412 412 413 - callchain_param_setup(sample_type); 413 + callchain_param_setup(sample_type, perf_env__arch(&rep->session->header.env)); 414 414 415 415 if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) { 416 416 ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n" ··· 1127 1127 * on events sample_type. 1128 1128 */ 1129 1129 sample_type = evlist__combined_sample_type(*pevlist); 1130 - callchain_param_setup(sample_type); 1130 + callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env)); 1131 1131 return 0; 1132 1132 } 1133 1133
+2 -2
tools/perf/builtin-script.c
··· 2318 2318 * on events sample_type. 2319 2319 */ 2320 2320 sample_type = evlist__combined_sample_type(evlist); 2321 - callchain_param_setup(sample_type); 2321 + callchain_param_setup(sample_type, perf_env__arch((*pevlist)->env)); 2322 2322 2323 2323 /* Enable fields for callchain entries */ 2324 2324 if (symbol_conf.use_callchain && ··· 3468 3468 struct perf_session *session = script->session; 3469 3469 u64 sample_type = evlist__combined_sample_type(session->evlist); 3470 3470 3471 - callchain_param_setup(sample_type); 3471 + callchain_param_setup(sample_type, perf_env__arch(session->machines.host.env)); 3472 3472 3473 3473 if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) { 3474 3474 pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
+13 -1
tools/perf/util/callchain.c
··· 1600 1600 map__zput(node->ms.map); 1601 1601 } 1602 1602 1603 - void callchain_param_setup(u64 sample_type) 1603 + void callchain_param_setup(u64 sample_type, const char *arch) 1604 1604 { 1605 1605 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { 1606 1606 if ((sample_type & PERF_SAMPLE_REGS_USER) && ··· 1612 1612 else 1613 1613 callchain_param.record_mode = CALLCHAIN_FP; 1614 1614 } 1615 + 1616 + /* 1617 + * It's necessary to use libunwind to reliably determine the caller of 1618 + * a leaf function on aarch64, as otherwise we cannot know whether to 1619 + * start from the LR or FP. 1620 + * 1621 + * Always starting from the LR can result in duplicate or entirely 1622 + * erroneous entries. Always skipping the LR and starting from the FP 1623 + * can result in missing entries. 1624 + */ 1625 + if (callchain_param.record_mode == CALLCHAIN_FP && !strcmp(arch, "arm64")) 1626 + dwarf_callchain_users = true; 1615 1627 } 1616 1628 1617 1629 static bool chain_match(struct callchain_list *base_chain,
+1 -1
tools/perf/util/callchain.h
··· 300 300 u64 *branch_count, u64 *predicted_count, 301 301 u64 *abort_count, u64 *cycles_count); 302 302 303 - void callchain_param_setup(u64 sample_type); 303 + void callchain_param_setup(u64 sample_type, const char *arch); 304 304 305 305 bool callchain_cnode_matched(struct callchain_node *base_cnode, 306 306 struct callchain_node *pair_cnode);