mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
perf cs-etm: Respect --no-itrace option
If there is a bug in decoding then Perf will exit early and you can't investigate by using the raw dump mode. Make the --no-itrace option stop Coresight decoding after printing the aux header so decode errors don't stop the rest of the samples being printed. pmu_type and evsel_is_auxtrace need to be set so that the unleader_auxtrace() behavior is the same as without --no-itrace. Reviewed-by: Adrian Hunter <adrian.hunter@intel.com> Reviewed-by: Leo Yan <leo.yan@arm.com> Signed-off-by: James Clark <james.clark@linaro.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e4c26138ec
commit
746cd5440b
|
|
@ -123,7 +123,7 @@ static int evlist__regroup(struct evlist *evlist, struct evsel *leader, struct e
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool auxtrace__dont_decode(struct perf_session *session)
|
||||
bool auxtrace__dont_decode(struct perf_session *session)
|
||||
{
|
||||
return !session->itrace_synth_opts ||
|
||||
session->itrace_synth_opts->dont_decode;
|
||||
|
|
|
|||
|
|
@ -650,6 +650,7 @@ void auxtrace__free(struct perf_session *session);
|
|||
bool auxtrace__evsel_is_auxtrace(struct perf_session *session,
|
||||
struct evsel *evsel);
|
||||
u64 auxtrace_synth_id_range_start(struct evsel *evsel);
|
||||
bool auxtrace__dont_decode(struct perf_session *session);
|
||||
|
||||
#define ITRACE_HELP \
|
||||
" i[period]: synthesize instructions events\n" \
|
||||
|
|
|
|||
|
|
@ -965,7 +965,7 @@ static int cs_etm__flush_events(struct perf_session *session,
|
|||
struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
|
||||
struct cs_etm_auxtrace,
|
||||
auxtrace);
|
||||
if (dump_trace)
|
||||
if (dump_trace || auxtrace__dont_decode(session))
|
||||
return 0;
|
||||
|
||||
if (!tool->ordered_events)
|
||||
|
|
@ -3002,7 +3002,7 @@ static int cs_etm__process_event(struct perf_session *session,
|
|||
struct cs_etm_auxtrace,
|
||||
auxtrace);
|
||||
|
||||
if (dump_trace)
|
||||
if (dump_trace || auxtrace__dont_decode(session))
|
||||
return 0;
|
||||
|
||||
if (!tool->ordered_events) {
|
||||
|
|
@ -3552,27 +3552,49 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
int err = 0;
|
||||
int aux_hw_id_found;
|
||||
int i;
|
||||
u64 *ptr = NULL;
|
||||
u64 *ptr = (u64 *) auxtrace_info->priv;
|
||||
u64 **metadata = NULL;
|
||||
|
||||
/* First the global part */
|
||||
ptr = (u64 *) auxtrace_info->priv;
|
||||
num_cpu = ptr[CS_PMU_TYPE_CPUS] & 0xffffffff;
|
||||
etm = zalloc(sizeof(*etm));
|
||||
if (!etm)
|
||||
return -ENOMEM;
|
||||
|
||||
session->auxtrace = &etm->auxtrace;
|
||||
etm->auxtrace.free = cs_etm__free;
|
||||
etm->auxtrace.evsel_is_auxtrace = cs_etm__evsel_is_auxtrace;
|
||||
etm->auxtrace.process_event = cs_etm__process_event;
|
||||
etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
|
||||
etm->auxtrace.flush_events = cs_etm__flush_events;
|
||||
etm->auxtrace.free_events = cs_etm__free_events;
|
||||
etm->pmu_type = (unsigned int) ((ptr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff);
|
||||
|
||||
/*
|
||||
* Don't go further than the minimum required to identify this event as
|
||||
* auxtrace with cs_etm__evsel_is_auxtrace() so unleader_auxtrace()
|
||||
* works.
|
||||
*/
|
||||
if (auxtrace__dont_decode(session))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Bound num_cpu by the event size: the global header consumes
|
||||
* CS_ETM_HEADER_SIZE bytes, and each CPU needs at least one u64
|
||||
* metadata entry after that.
|
||||
*/
|
||||
num_cpu = ptr[CS_PMU_TYPE_CPUS] & 0xffffffff;
|
||||
priv_size = total_size - event_header_size - INFO_HEADER_SIZE -
|
||||
CS_ETM_HEADER_SIZE;
|
||||
if (num_cpu <= 0 || priv_size <= 0 ||
|
||||
num_cpu > priv_size / (int)sizeof(u64))
|
||||
return -EINVAL;
|
||||
num_cpu > priv_size / (int)sizeof(u64)) {
|
||||
err = -EINVAL;
|
||||
goto err_free_etm;
|
||||
}
|
||||
|
||||
metadata = zalloc(sizeof(*metadata) * num_cpu);
|
||||
if (!metadata)
|
||||
return -ENOMEM;
|
||||
if (!metadata) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_etm;
|
||||
}
|
||||
|
||||
/* Start parsing after the common part of the header */
|
||||
i = CS_HEADER_VERSION_MAX;
|
||||
|
|
@ -3631,13 +3653,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
goto err_free_metadata;
|
||||
}
|
||||
|
||||
etm = zalloc(sizeof(*etm));
|
||||
|
||||
if (!etm) {
|
||||
err = -ENOMEM;
|
||||
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
|
||||
|
|
@ -3647,7 +3662,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
|
||||
err = auxtrace_queues__init_nr(&etm->queues, max_cpu + 1);
|
||||
if (err)
|
||||
goto err_free_etm;
|
||||
goto err_free_metadata;
|
||||
|
||||
for (unsigned int j = 0; j < etm->queues.nr_queues; ++j) {
|
||||
err = cs_etm__setup_queue(etm, &etm->queues.queue_array[j], j);
|
||||
|
|
@ -3685,7 +3700,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
etm->session = session;
|
||||
|
||||
etm->num_cpu = num_cpu;
|
||||
etm->pmu_type = (unsigned int) ((ptr[CS_PMU_TYPE_CPUS] >> 32) & 0xffffffff);
|
||||
etm->snapshot_mode = (ptr[CS_ETM_SNAPSHOT] != 0);
|
||||
etm->metadata = metadata;
|
||||
etm->auxtrace_type = auxtrace_info->type;
|
||||
|
|
@ -3712,14 +3726,6 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
"you can specify the itrace option 'T' for timestamp decoding\n"
|
||||
"if the Coresight timestamp on the platform is same with the kernel time.\n\n");
|
||||
|
||||
etm->auxtrace.process_event = cs_etm__process_event;
|
||||
etm->auxtrace.process_auxtrace_event = cs_etm__process_auxtrace_event;
|
||||
etm->auxtrace.flush_events = cs_etm__flush_events;
|
||||
etm->auxtrace.free_events = cs_etm__free_events;
|
||||
etm->auxtrace.free = cs_etm__free;
|
||||
etm->auxtrace.evsel_is_auxtrace = cs_etm__evsel_is_auxtrace;
|
||||
session->auxtrace = &etm->auxtrace;
|
||||
|
||||
cs_etm__setup_timeless_decoding(etm);
|
||||
|
||||
etm->tc.time_shift = tc->time_shift;
|
||||
|
|
@ -3797,13 +3803,13 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event,
|
|||
|
||||
err_free_queues:
|
||||
cs_etm__free_queues(etm);
|
||||
session->auxtrace = NULL;
|
||||
err_free_etm:
|
||||
zfree(&etm);
|
||||
err_free_metadata:
|
||||
/* No need to check @metadata[j], free(NULL) is supported */
|
||||
for (int j = 0; j < num_cpu; j++)
|
||||
zfree(&metadata[j]);
|
||||
zfree(&metadata);
|
||||
err_free_etm:
|
||||
session->auxtrace = NULL;
|
||||
zfree(&etm);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user