perf cs-etm: Move mapping of Trace ID and cpu into helper function
The information to associate Trace ID and CPU will be changing. Drivers will start outputting this as a hardware ID packet in the data file which if present will be used in preference to the AUXINFO values. To prepare for this we provide a helper functions to do the individual ID mapping, and one to extract the IDs from the completed metadata blocks. Reviewed-by: James Clark <james.clark@arm.com> Signed-off-by: Mike Leach <mike.leach@linaro.org> Acked-by: Suzuki Poulouse <suzuki.poulose@arm.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Darren Hart <darren@os.amperecomputing.com> Cc: Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Will Deacon <will@kernel.org> Cc: coresight@lists.linaro.org Cc: linux-arm-kernel@lists.infradead.org Link: https://lore.kernel.org/r/20230331055645.26918-2-mike.leach@linaro.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Родитель
84c3a2bb4c
Коммит
0927729555
|
@ -7,9 +7,14 @@
|
|||
#ifndef _LINUX_CORESIGHT_PMU_H
|
||||
#define _LINUX_CORESIGHT_PMU_H
|
||||
|
||||
#include <linux/bits.h>
|
||||
|
||||
#define CORESIGHT_ETM_PMU_NAME "cs_etm"
|
||||
#define CORESIGHT_ETM_PMU_SEED 0x10
|
||||
|
||||
/* CoreSight trace ID is currently the bottom 7 bits of the value */
|
||||
#define CORESIGHT_TRACE_ID_VAL_MASK GENMASK(6, 0)
|
||||
|
||||
/*
|
||||
* Below are the definition of bit offsets for perf option, and works as
|
||||
* arbitrary values for all ETM versions.
|
||||
|
|
|
@ -148,7 +148,8 @@ static void cs_etm__print_auxtrace_info(u64 *val, int num)
|
|||
for (i = CS_HEADER_VERSION_MAX; cpu < num; cpu++) {
|
||||
if (version == 0)
|
||||
err = cs_etm__print_cpu_metadata_v0(val, &i);
|
||||
else if (version == 1)
|
||||
/* printing same for both, but value bit flags added on v2 */
|
||||
else if ((version == 1) || (version == 2))
|
||||
err = cs_etm__print_cpu_metadata_v1(val, &i);
|
||||
if (err)
|
||||
return;
|
||||
|
|
|
@ -196,6 +196,30 @@ int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cs_etm__map_trace_id(u8 trace_chan_id, u64 *cpu_metadata)
|
||||
{
|
||||
struct int_node *inode;
|
||||
|
||||
/* Get an RB node for this CPU */
|
||||
inode = intlist__findnew(traceid_list, trace_chan_id);
|
||||
|
||||
/* Something went wrong, no need to continue */
|
||||
if (!inode)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* The node for that CPU should not be taken.
|
||||
* Back out if that's the case.
|
||||
*/
|
||||
if (inode->priv)
|
||||
return -EINVAL;
|
||||
|
||||
/* All good, associate the traceID with the metadata pointer */
|
||||
inode->priv = cpu_metadata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
|
||||
u8 trace_chan_id)
|
||||
{
|
||||
|
@ -2804,17 +2828,46 @@ static bool cs_etm__has_virtual_ts(u64 **metadata, int num_cpu)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* map trace ids to correct metadata block, from information in metadata */
|
||||
static int cs_etm__map_trace_ids_metadata(int num_cpu, u64 **metadata)
|
||||
{
|
||||
u64 cs_etm_magic;
|
||||
u8 trace_chan_id;
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < num_cpu; i++) {
|
||||
cs_etm_magic = metadata[i][CS_ETM_MAGIC];
|
||||
switch (cs_etm_magic) {
|
||||
case __perf_cs_etmv3_magic:
|
||||
trace_chan_id = (u8)((metadata[i][CS_ETM_ETMTRACEIDR]) &
|
||||
CORESIGHT_TRACE_ID_VAL_MASK);
|
||||
break;
|
||||
case __perf_cs_etmv4_magic:
|
||||
case __perf_cs_ete_magic:
|
||||
trace_chan_id = (u8)((metadata[i][CS_ETMV4_TRCTRACEIDR]) &
|
||||
CORESIGHT_TRACE_ID_VAL_MASK);
|
||||
break;
|
||||
default:
|
||||
/* unknown magic number */
|
||||
return -EINVAL;
|
||||
}
|
||||
err = cs_etm__map_trace_id(trace_chan_id, metadata[i]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
||||
struct perf_session *session)
|
||||
{
|
||||
struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
|
||||
struct cs_etm_auxtrace *etm = NULL;
|
||||
struct int_node *inode;
|
||||
struct perf_record_time_conv *tc = &session->time_conv;
|
||||
int event_header_size = sizeof(struct perf_event_header);
|
||||
int total_size = auxtrace_info->header.size;
|
||||
int priv_size = 0;
|
||||
int num_cpu, trcidr_idx;
|
||||
int num_cpu;
|
||||
int err = 0;
|
||||
int i, j;
|
||||
u64 *ptr = NULL;
|
||||
|
@ -2853,23 +2906,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
cs_etm__create_meta_blk(ptr, &i,
|
||||
CS_ETM_PRIV_MAX,
|
||||
CS_ETM_NR_TRC_PARAMS_V0);
|
||||
|
||||
/* The traceID is our handle */
|
||||
trcidr_idx = CS_ETM_ETMTRACEIDR;
|
||||
|
||||
} else if (ptr[i] == __perf_cs_etmv4_magic) {
|
||||
metadata[j] =
|
||||
cs_etm__create_meta_blk(ptr, &i,
|
||||
CS_ETMV4_PRIV_MAX,
|
||||
CS_ETMV4_NR_TRC_PARAMS_V0);
|
||||
|
||||
/* The traceID is our handle */
|
||||
trcidr_idx = CS_ETMV4_TRCTRACEIDR;
|
||||
} else if (ptr[i] == __perf_cs_ete_magic) {
|
||||
metadata[j] = cs_etm__create_meta_blk(ptr, &i, CS_ETE_PRIV_MAX, -1);
|
||||
|
||||
/* ETE shares first part of metadata with ETMv4 */
|
||||
trcidr_idx = CS_ETMV4_TRCTRACEIDR;
|
||||
} else {
|
||||
ui__error("CS ETM Trace: Unrecognised magic number %#"PRIx64". File could be from a newer version of perf.\n",
|
||||
ptr[i]);
|
||||
|
@ -2881,26 +2924,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
err = -ENOMEM;
|
||||
goto err_free_metadata;
|
||||
}
|
||||
|
||||
/* Get an RB node for this CPU */
|
||||
inode = intlist__findnew(traceid_list, metadata[j][trcidr_idx]);
|
||||
|
||||
/* Something went wrong, no need to continue */
|
||||
if (!inode) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_metadata;
|
||||
}
|
||||
|
||||
/*
|
||||
* The node for that CPU should not be taken.
|
||||
* Back out if that's the case.
|
||||
*/
|
||||
if (inode->priv) {
|
||||
err = -EINVAL;
|
||||
goto err_free_metadata;
|
||||
}
|
||||
/* All good, associate the traceID with the metadata pointer */
|
||||
inode->priv = metadata[j];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2994,6 +3017,11 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
if (err)
|
||||
goto err_delete_thread;
|
||||
|
||||
/* before aux records are queued, need to map metadata to trace IDs */
|
||||
err = cs_etm__map_trace_ids_metadata(num_cpu, metadata);
|
||||
if (err)
|
||||
goto err_delete_thread;
|
||||
|
||||
err = cs_etm__queue_aux_records(session);
|
||||
if (err)
|
||||
goto err_delete_thread;
|
||||
|
|
|
@ -29,13 +29,17 @@ enum {
|
|||
/*
|
||||
* Update the version for new format.
|
||||
*
|
||||
* New version 1 format adds a param count to the per cpu metadata.
|
||||
* Version 1: format adds a param count to the per cpu metadata.
|
||||
* This allows easy adding of new metadata parameters.
|
||||
* Requires that new params always added after current ones.
|
||||
* Also allows client reader to handle file versions that are different by
|
||||
* checking the number of params in the file vs the number expected.
|
||||
*
|
||||
* Version 2: Drivers will use PERF_RECORD_AUX_OUTPUT_HW_ID to output
|
||||
* CoreSight Trace ID. ...TRACEIDR metadata will be set to legacy values
|
||||
* but with addition flags.
|
||||
*/
|
||||
#define CS_HEADER_CURRENT_VERSION 1
|
||||
#define CS_HEADER_CURRENT_VERSION 2
|
||||
|
||||
/* Beginning of header common to both ETMv3 and V4 */
|
||||
enum {
|
||||
|
@ -97,6 +101,12 @@ enum {
|
|||
CS_ETE_PRIV_MAX
|
||||
};
|
||||
|
||||
/*
|
||||
* Check for valid CoreSight trace ID. If an invalid value is present in the metadata,
|
||||
* then IDs are present in the hardware ID packet in the data file.
|
||||
*/
|
||||
#define CS_IS_VALID_TRACE_ID(id) ((id > 0) && (id < 0x70))
|
||||
|
||||
/*
|
||||
* ETMv3 exception encoding number:
|
||||
* See Embedded Trace Macrocell specification (ARM IHI 0014Q)
|
||||
|
|
Загрузка…
Ссылка в новой задаче