From 5414b532611b19671cb10813e5d56e011574d698 Mon Sep 17 00:00:00 2001 From: James Clark Date: Mon, 12 Jun 2023 12:14:00 +0100 Subject: perf cs-etm: Make PID format accessible from struct cs_etm_auxtrace To avoid every user of PID format having to use their own static local variable, cache it on initialisation and change the accessor to take struct cs_etm_auxtrace. Reviewed-by: Leo Yan Signed-off-by: James Clark Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Garry Cc: Mark Rutland Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: Will Deacon Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230612111403.100613-4-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'tools/perf/util/cs-etm.c') diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index da22732e50f6..8c4d55a802b0 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -78,6 +78,7 @@ struct cs_etm_auxtrace { u64 instructions_id; u64 **metadata; unsigned int pmu_type; + enum cs_etm_pid_fmt pid_fmt; }; struct cs_etm_traceid_queue { @@ -170,44 +171,46 @@ int cs_etm__get_cpu(u8 trace_chan_id, int *cpu) } /* - * The returned PID format is presented by two bits: + * The returned PID format is presented as an enum: * - * Bit ETM_OPT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced; - * Bit ETM_OPT_CTXTID2: CONTEXTIDR_EL2 is traced. + * CS_ETM_PIDFMT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced. + * CS_ETM_PIDFMT_CTXTID2: CONTEXTIDR_EL2 is traced. + * CS_ETM_PIDFMT_NONE: No context IDs * * It's possible that the two bits ETM_OPT_CTXTID and ETM_OPT_CTXTID2 * are enabled at the same time when the session runs on an EL2 kernel. * This means the CONTEXTIDR_EL1 and CONTEXTIDR_EL2 both will be * recorded in the trace data, the tool will selectively use * CONTEXTIDR_EL2 as PID. + * + * The result is cached in etm->pid_fmt so this function only needs to be called + * when processing the aux info. */ -int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt) +static enum cs_etm_pid_fmt cs_etm__init_pid_fmt(u64 *metadata) { - struct int_node *inode; - u64 *metadata, val; - - inode = intlist__find(traceid_list, trace_chan_id); - if (!inode) - return -EINVAL; - - metadata = inode->priv; + u64 val; if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) { val = metadata[CS_ETM_ETMCR]; /* CONTEXTIDR is traced */ if (val & BIT(ETM_OPT_CTXTID)) - *pid_fmt = BIT(ETM_OPT_CTXTID); + return CS_ETM_PIDFMT_CTXTID; } else { val = metadata[CS_ETMV4_TRCCONFIGR]; /* CONTEXTIDR_EL2 is traced */ if (val & (BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT))) - *pid_fmt = BIT(ETM_OPT_CTXTID2); + return CS_ETM_PIDFMT_CTXTID2; /* CONTEXTIDR_EL1 is traced */ else if (val & BIT(ETM4_CFG_BIT_CTXTID)) - *pid_fmt = BIT(ETM_OPT_CTXTID); + return CS_ETM_PIDFMT_CTXTID; } - return 0; + return CS_ETM_PIDFMT_NONE; +} + +enum cs_etm_pid_fmt cs_etm__get_pid_fmt(struct cs_etm_queue *etmq) +{ + return etmq->etm->pid_fmt; } static int cs_etm__map_trace_id(u8 trace_chan_id, u64 *cpu_metadata) @@ -3239,6 +3242,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, goto err_free_metadata; } + /* + * As all the ETMs run at the same exception level, the system should + * have the same PID format crossing CPUs. So cache the PID format + * and reuse it for sequential decoding. + */ + etm->pid_fmt = cs_etm__init_pid_fmt(metadata[0]); + err = auxtrace_queues__init(&etm->queues); if (err) goto err_free_etm; -- cgit v1.2.3-70-g09d2