-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf tools: Add initial entry point for decoder CoreSight traces
This patch adds the entry point for CoreSight trace decoding, serving as a jumping board for furhter expansions. Co-authored-by: Tor Jeremiassen <tor@ti.com> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Kim Phillips <kim.phillips@arm.com> Cc: Mike Leach <mike.leach@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Suzuki Poulouse <suzuki.poulose@arm.com> Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1516211539-5166-3-git-send-email-mathieu.poirier@linaro.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
- Loading branch information
2 people
authored and
Arnaldo Carvalho de Melo
committed
Jan 25, 2018
1 parent
aa6292f
commit 440a23b
Showing
4 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
/* | ||
* SPDX-License-Identifier: GPL-2.0 | ||
* | ||
* Copyright(C) 2015-2018 Linaro Limited. | ||
* | ||
* Author: Tor Jeremiassen <tor@ti.com> | ||
* Author: Mathieu Poirier <mathieu.poirier@linaro.org> | ||
*/ | ||
|
||
#include <linux/bitops.h> | ||
#include <linux/err.h> | ||
#include <linux/kernel.h> | ||
#include <linux/log2.h> | ||
#include <linux/types.h> | ||
|
||
#include <stdlib.h> | ||
|
||
#include "auxtrace.h" | ||
#include "color.h" | ||
#include "cs-etm.h" | ||
#include "debug.h" | ||
#include "evlist.h" | ||
#include "intlist.h" | ||
#include "machine.h" | ||
#include "map.h" | ||
#include "perf.h" | ||
#include "thread.h" | ||
#include "thread_map.h" | ||
#include "thread-stack.h" | ||
#include "util.h" | ||
|
||
#define MAX_TIMESTAMP (~0ULL) | ||
|
||
struct cs_etm_auxtrace { | ||
struct auxtrace auxtrace; | ||
struct auxtrace_queues queues; | ||
struct auxtrace_heap heap; | ||
struct itrace_synth_opts synth_opts; | ||
struct perf_session *session; | ||
struct machine *machine; | ||
struct thread *unknown_thread; | ||
|
||
u8 timeless_decoding; | ||
u8 snapshot_mode; | ||
u8 data_queued; | ||
u8 sample_branches; | ||
|
||
int num_cpu; | ||
u32 auxtrace_type; | ||
u64 branches_sample_type; | ||
u64 branches_id; | ||
u64 **metadata; | ||
u64 kernel_start; | ||
unsigned int pmu_type; | ||
}; | ||
|
||
struct cs_etm_queue { | ||
struct cs_etm_auxtrace *etm; | ||
struct thread *thread; | ||
struct cs_etm_decoder *decoder; | ||
struct auxtrace_buffer *buffer; | ||
const struct cs_etm_state *state; | ||
union perf_event *event_buf; | ||
unsigned int queue_nr; | ||
pid_t pid, tid; | ||
int cpu; | ||
u64 time; | ||
u64 timestamp; | ||
u64 offset; | ||
}; | ||
|
||
static int cs_etm__flush_events(struct perf_session *session, | ||
struct perf_tool *tool) | ||
{ | ||
(void) session; | ||
(void) tool; | ||
return 0; | ||
} | ||
|
||
static void cs_etm__free_queue(void *priv) | ||
{ | ||
struct cs_etm_queue *etmq = priv; | ||
|
||
free(etmq); | ||
} | ||
|
||
static void cs_etm__free_events(struct perf_session *session) | ||
{ | ||
unsigned int i; | ||
struct cs_etm_auxtrace *aux = container_of(session->auxtrace, | ||
struct cs_etm_auxtrace, | ||
auxtrace); | ||
struct auxtrace_queues *queues = &aux->queues; | ||
|
||
for (i = 0; i < queues->nr_queues; i++) { | ||
cs_etm__free_queue(queues->queue_array[i].priv); | ||
queues->queue_array[i].priv = NULL; | ||
} | ||
|
||
auxtrace_queues__free(queues); | ||
} | ||
|
||
static void cs_etm__free(struct perf_session *session) | ||
{ | ||
struct cs_etm_auxtrace *aux = container_of(session->auxtrace, | ||
struct cs_etm_auxtrace, | ||
auxtrace); | ||
cs_etm__free_events(session); | ||
session->auxtrace = NULL; | ||
|
||
zfree(&aux); | ||
} | ||
|
||
static int cs_etm__process_event(struct perf_session *session, | ||
union perf_event *event, | ||
struct perf_sample *sample, | ||
struct perf_tool *tool) | ||
{ | ||
(void) session; | ||
(void) event; | ||
(void) sample; | ||
(void) tool; | ||
return 0; | ||
} | ||
|
||
static int cs_etm__process_auxtrace_event(struct perf_session *session, | ||
union perf_event *event, | ||
struct perf_tool *tool) | ||
{ | ||
(void) session; | ||
(void) event; | ||
(void) tool; | ||
return 0; | ||
} | ||
|
||
static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm) | ||
{ | ||
struct perf_evsel *evsel; | ||
struct perf_evlist *evlist = etm->session->evlist; | ||
bool timeless_decoding = true; | ||
|
||
/* | ||
* Circle through the list of event and complain if we find one | ||
* with the time bit set. | ||
*/ | ||
evlist__for_each_entry(evlist, evsel) { | ||
if ((evsel->attr.sample_type & PERF_SAMPLE_TIME)) | ||
timeless_decoding = false; | ||
} | ||
|
||
return timeless_decoding; | ||
} | ||
|
||
int cs_etm__process_auxtrace_info(union perf_event *event, | ||
struct perf_session *session) | ||
{ | ||
struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info; | ||
struct cs_etm_auxtrace *etm = NULL; | ||
int event_header_size = sizeof(struct perf_event_header); | ||
int info_header_size; | ||
int total_size = auxtrace_info->header.size; | ||
int err = 0; | ||
|
||
/* | ||
* sizeof(auxtrace_info_event::type) + | ||
* sizeof(auxtrace_info_event::reserved) == 8 | ||
*/ | ||
info_header_size = 8; | ||
|
||
if (total_size < (event_header_size + info_header_size)) | ||
return -EINVAL; | ||
|
||
etm = zalloc(sizeof(*etm)); | ||
|
||
if (!etm) | ||
err = -ENOMEM; | ||
|
||
err = auxtrace_queues__init(&etm->queues); | ||
if (err) | ||
goto err_free_etm; | ||
|
||
etm->session = session; | ||
etm->machine = &session->machines.host; | ||
|
||
etm->auxtrace_type = auxtrace_info->type; | ||
etm->timeless_decoding = cs_etm__is_timeless_decoding(etm); | ||
|
||
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; | ||
session->auxtrace = &etm->auxtrace; | ||
|
||
if (dump_trace) | ||
return 0; | ||
|
||
err = auxtrace_queues__process_index(&etm->queues, session); | ||
if (err) | ||
goto err_free_queues; | ||
|
||
etm->data_queued = etm->queues.populated; | ||
|
||
return 0; | ||
|
||
err_free_queues: | ||
auxtrace_queues__free(&etm->queues); | ||
session->auxtrace = NULL; | ||
err_free_etm: | ||
zfree(&etm); | ||
|
||
return -EINVAL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters