On Fri, Sep 22, 2017 at 04:03:18AM -0500, Tor Jeremiassen wrote:
Adds new file cs-etm.c that adds auxtrace info event handler for cs-etm (coresight ETM) traces, event handling data structures and the necessary callback functions required to be provided in the auxtrace struct.
The coresight trace decoding is enabled by setting the CSTRACE_PATH environment variable to point to the decoder subdirectory in the coresight trace decoder library.
Signed-off-by: Tor Jeremiassen tor@ti.com
tools/perf/Makefile.config | 5 + tools/perf/util/Build | 5 + tools/perf/util/auxtrace.c | 2 + tools/perf/util/cs-etm.c | 230 +++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cs-etm.h | 16 ++++ 5 files changed, 258 insertions(+) create mode 100644 tools/perf/util/cs-etm.c
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 63f534a..d1a83aa 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -339,6 +339,11 @@ ifeq ($(feature-setns), 1) $(call detected,CONFIG_SETNS) endif +ifdef CSTRACE_PATH
- CFLAGS += -DHAVE_CSTRACE_SUPPORT
- CFLAGS-$(CONFIG_AUXTRACE) += -DHAVE_CSTRACE_SUPPORT
I couldn't figure out what the above line was doing so I removed it.
+endif
ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT EXTLIBS += -lelf diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 94518c1..23439f4 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -83,6 +83,11 @@ libperf-$(CONFIG_AUXTRACE) += auxtrace.o libperf-$(CONFIG_AUXTRACE) += intel-pt-decoder/ libperf-$(CONFIG_AUXTRACE) += intel-pt.o libperf-$(CONFIG_AUXTRACE) += intel-bts.o
+ifdef CSTRACE_PATH +libperf-$(CONFIG_AUXTRACE) += cs-etm.o +endif
libperf-y += parse-branch-options.o libperf-y += dump-insn.o libperf-y += parse-regs-options.o diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 5547457..37f9d08 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -55,6 +55,7 @@ #include "debug.h" #include <subcmd/parse-options.h> +#include "cs-etm.h" #include "intel-pt.h" #include "intel-bts.h" @@ -914,6 +915,7 @@ int perf_event__process_auxtrace_info(struct perf_tool *tool __maybe_unused, case PERF_AUXTRACE_INTEL_BTS: return intel_bts_process_auxtrace_info(event, session); case PERF_AUXTRACE_CS_ETM:
case PERF_AUXTRACE_UNKNOWN: default: return -EINVAL;return cs_etm__process_auxtrace_info(event, session);
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c new file mode 100644 index 0000000..e3f4e86 --- /dev/null +++ b/tools/perf/util/cs-etm.c @@ -0,0 +1,230 @@ +/*
- Copyright(C) 2015-2017 Linaro Limited. All rights reserved.
- Author: Tor Jeremiassen tor@ti.com
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 as published by
- the Free Software Foundation.
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
- You should have received a copy of the GNU General Public License along with
- this program. If not, see http://www.gnu.org/licenses/.
- */
+#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 "perf.h" +#include "thread.h" +#include "thread_map.h" +#include "thread-stack.h" +#include "util.h"
+struct cs_etm_auxtrace {
- struct auxtrace auxtrace;
- struct auxtrace_queues queues;
- struct auxtrace_heap heap;
- u64 **metadata;
- u32 auxtrace_type;
- struct perf_session *session;
- struct machine *machine;
- struct perf_evsel *switch_evsel;
- struct thread *unknown_thread;
- uint32_t num_cpu;
- bool timeless_decoding;
- bool sampling_mode;
- bool snapshot_mode;
- bool data_queued;
- bool synth_needs_swap;
- bool sample_instructions;
- u64 instructions_sample_type;
- u64 instructions_sample_period;
- u64 instructions_id;
- struct itrace_synth_opts synth_opts;
- unsigned int pmu_type;
- u64 kernel_start;
+};
+struct cs_etm_queue {
- struct cs_etm_auxtrace *etm;
- unsigned int queue_nr;
- struct auxtrace_buffer *buffer;
- const struct cs_etm_state *state;
- union perf_event *event_buf;
- bool on_heap;
- bool step_through_buffers;
- bool use_buffer_pid_tid;
- pid_t pid, tid;
- int cpu;
- struct thread *thread;
- u64 time;
- u64 timestamp;
- bool stop;
- struct cs_etm_decoder *decoder;
- u64 offset;
- bool eot;
+};
+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;
- if (!etmq)
return;
- thread__zput(etmq->thread);
- free(etmq);
+}
+static void cs_etm__free_events(struct perf_session *session) +{
- struct cs_etm_auxtrace *aux = container_of(session->auxtrace,
struct cs_etm_auxtrace,
auxtrace);
- struct auxtrace_queues *queues = &aux->queues;
- unsigned int i;
- 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);
- auxtrace_heap__free(&aux->heap);
- 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;
+}
+int cs_etm__process_auxtrace_info(union perf_event *event,
struct perf_session *session)
+{
- struct auxtrace_info_event *auxtrace_info = &event->auxtrace_info;
- size_t event_header_size = sizeof(struct perf_event_header);
- size_t info_header_size;
- size_t total_size = auxtrace_info->header.size;
- struct cs_etm_auxtrace *etm = NULL;
- 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)
return -ENOMEM;
- err = auxtrace_queues__init(&etm->queues);
- if (err)
goto err_free_etm;
- etm->unknown_thread = thread__new(999999999, 999999999);
- if (!etm->unknown_thread) {
err = -ENOMEM;
goto err_free_queues;
- }
- err = thread__set_comm(etm->unknown_thread, "unknown", 0);
- if (err)
goto err_delete_thread;
- etm->session = session;
- etm->machine = &session->machines.host;
- etm->kernel_start = machine__kernel_start(etm->machine);
- if (thread__init_map_groups(etm->unknown_thread,
etm->machine)) {
err = -ENOMEM;
goto err_delete_thread;
- }
- etm->auxtrace_type = auxtrace_info->type;
- 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_delete_thread;
- etm->data_queued = etm->queues.populated;
- return 0;
+err_delete_thread:
- thread__delete(etm->unknown_thread);
+err_free_queues:
- auxtrace_queues__free(&etm->queues);
- session->auxtrace = NULL;
+err_free_etm:
- zfree(&etm);
- return err;
+} diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 3cc6bc3..9e43ede 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -18,6 +18,9 @@ #ifndef INCLUDE__UTIL_PERF_CS_ETM_H__ #define INCLUDE__UTIL_PERF_CS_ETM_H__ +#include "util/event.h" +#include "util/session.h"
/* Versionning header in case things need tro change in the future. That way
- decoding of old snapshot is still possible.
*/ @@ -71,4 +74,17 @@ static const u64 __perf_cs_etmv4_magic = 0x4040404040404040ULL; #define CS_ETMV3_PRIV_SIZE (CS_ETM_PRIV_MAX * sizeof(u64)) #define CS_ETMV4_PRIV_SIZE (CS_ETMV4_PRIV_MAX * sizeof(u64)) +#ifdef HAVE_CSTRACE_SUPPORT +int cs_etm__process_auxtrace_info(union perf_event *event,
struct perf_session *session);
+#else +static inline int cs_etm__process_auxtrace_info(union perf_event *event,
struct perf_session *session)
+{
- (void) event;
- (void) session;
- return -1;
+} +#endif
#endif
2.7.4
CoreSight mailing list CoreSight@lists.linaro.org https://lists.linaro.org/mailman/listinfo/coresight