Skip to content

Commit

Permalink
perf cs-etm: Add PID format into metadata
Browse files Browse the repository at this point in the history
It's possible for CoreSight to trace PID in either CONTEXTIDR_EL1 or
CONTEXTIDR_EL2, the PID format info can be used to distinguish the PID
is traced in which register.

This patch saves PID format value into the metadata when record the
trace data; during the decoding phase, it provides a helper function
cs_etm__get_pid_fmt() for easier retrieving PID format from metadata.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
  • Loading branch information
Leo Yan committed Nov 16, 2020
1 parent 32fc473 commit ba70531
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
21 changes: 21 additions & 0 deletions tools/perf/arch/arm/util/cs-etm.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
struct cs_etm_recording *ptr =
container_of(itr, struct cs_etm_recording, itr);
struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
u64 pid_fmt;

/* first see what kind of tracer this cpu is affined to */
if (cs_etm_is_etmv4(itr, cpu)) {
Expand Down Expand Up @@ -634,6 +635,16 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
metadata_etmv4_ro
[CS_ETMV4_TRCAUTHSTATUS]);

/*
* The PID format will be used when decode the trace data;
* based on it the decoder will make decision for setting
* sample's PID as context_id or VMID.
*/
pid_fmt = perf_pmu__format_bits(&cs_etm_pmu->format, "pid");
if (!pid_fmt)
pid_fmt = 1ULL << ETM_OPT_CTXTID;
info->priv[*offset + CS_ETMV4_PID_FMT] = pid_fmt;

/* How much space was used */
increment = CS_ETMV4_PRIV_MAX;
} else {
Expand All @@ -651,6 +662,16 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
cs_etm_get_ro(cs_etm_pmu, cpu,
metadata_etmv3_ro[CS_ETM_ETMIDR]);

/*
* The PID format will be used when decode the trace data;
* based on it the decoder will make decision for setting
* sample's PID as context_id or VMID.
*/
pid_fmt = perf_pmu__format_bits(&cs_etm_pmu->format, "pid");
if (!pid_fmt)
pid_fmt = 1ULL << ETM_OPT_CTXTID;
info->priv[*offset + CS_ETM_PID_FMT] = pid_fmt;

/* How much space was used */
increment = CS_ETM_PRIV_MAX;
}
Expand Down
21 changes: 21 additions & 0 deletions tools/perf/util/cs-etm.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,25 @@ int cs_etm__get_cpu(u8 trace_chan_id, int *cpu)
return 0;
}

int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt)
{
struct int_node *inode;
u64 *metadata;

inode = intlist__find(traceid_list, trace_chan_id);
if (!inode)
return -EINVAL;

metadata = inode->priv;

if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic)
*pid_fmt = (int)metadata[CS_ETM_PID_FMT];
else
*pid_fmt = (int)metadata[CS_ETMV4_PID_FMT];

return 0;
}

void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
u8 trace_chan_id)
{
Expand Down Expand Up @@ -2447,6 +2466,7 @@ static const char * const cs_etm_priv_fmts[] = {
[CS_ETM_ETMTRACEIDR] = " ETMTRACEIDR %llx\n",
[CS_ETM_ETMCCER] = " ETMCCER %llx\n",
[CS_ETM_ETMIDR] = " ETMIDR %llx\n",
[CS_ETM_PID_FMT] = " PID Format %llx\n",
};

static const char * const cs_etmv4_priv_fmts[] = {
Expand All @@ -2459,6 +2479,7 @@ static const char * const cs_etmv4_priv_fmts[] = {
[CS_ETMV4_TRCIDR2] = " TRCIDR2 %llx\n",
[CS_ETMV4_TRCIDR8] = " TRCIDR8 %llx\n",
[CS_ETMV4_TRCAUTHSTATUS] = " TRCAUTHSTATUS %llx\n",
[CS_ETMV4_PID_FMT] = " PID Format %llx\n",
};

static void cs_etm__print_auxtrace_info(__u64 *val, int num)
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/util/cs-etm.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ enum {
/* RO, taken from sysFS */
CS_ETM_ETMCCER,
CS_ETM_ETMIDR,
CS_ETM_PID_FMT,
CS_ETM_PRIV_MAX,
};

Expand All @@ -52,6 +53,7 @@ enum {
CS_ETMV4_TRCIDR2,
CS_ETMV4_TRCIDR8,
CS_ETMV4_TRCAUTHSTATUS,
CS_ETMV4_PID_FMT,
CS_ETMV4_PRIV_MAX,
};

Expand Down Expand Up @@ -173,6 +175,7 @@ struct cs_etm_packet_queue {
int cs_etm__process_auxtrace_info(union perf_event *event,
struct perf_session *session);
int cs_etm__get_cpu(u8 trace_chan_id, int *cpu);
int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt);
int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
pid_t tid, u8 trace_chan_id);
bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq);
Expand Down

0 comments on commit ba70531

Please sign in to comment.