From patchwork Fri Dec 15 16:44:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 122121 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp706323qgn; Fri, 15 Dec 2017 08:45:17 -0800 (PST) X-Google-Smtp-Source: ACJfBovY8Sce03vCXJO/PVcuY9KsvAcbERUb0gPL2uPhkUwh5+J1K/IhZ1McvLRhUYTXtakYBXT+ X-Received: by 10.84.217.14 with SMTP id o14mr7128642pli.169.1513356317424; Fri, 15 Dec 2017 08:45:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513356317; cv=none; d=google.com; s=arc-20160816; b=S76dNCPiWvjQFwV5MgN15LBnrxDgfUwKCkjNqYr07hgxb9iBsygd01EOil5XDPABhu 6b/xLrz7dFv3x1kokAh0i0l+bD50vdAt2F/9VhjiCnZhrupjysAzLBDsIaToR+I8jB1J 0BoP3EZj+MOquFX8BvdG4BTpMlNlEYXUvrPfilZtXI4gMWzbVXNajTnYbjaMzZelVfOv TEiRqSs2JIz+Hp3wjEGI+5pnB4llm6xkOMPd6qoDj7WmDuSRgm6cRUdYAJu5MpEYKonC tUeKKKbKbt/QU8C6MN3vGMPA5/NcZcmbDRlPjmPhH9I+g+/84Zg8thHBeTN0nGTjXRyt jsnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=nkJelSPBDg8JpR3T3TGdMqNYqX3NjJTFOmXPdYxFTc8=; b=ZFBCpsUomVp2GY3au81Dz6ZCaqpUxCcQJ40afwKwpI7OzoIlzd3Ix9XQSqhx1u0Q9a SnHGEExFE2bPSplDAf27mXMvkqjeuHdEONyA5Ylk5hvSQ4oYjJyCbLKFJ0AvuR7o8Q0c 70O7WNw48UFQtErLakqM9xaCH4q14GbXIryUcfbSf2aLITOXxL1cEEwVb+2VMJp1PemY TIVFn2fH5q0faTENS4DjDpip5LkpE9/uP5qLj+nANOvFXFzJmVW0ZKWBMvfXpBD3OlMH G3GFUeNinlNAoZLPHECubNHJxVokghhE7+Y/fUsOu8Nti0rTZl0RXqF9EX5uU791N1xe IoQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KtQPtlFq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x8si5132816plv.554.2017.12.15.08.45.17; Fri, 15 Dec 2017 08:45:17 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KtQPtlFq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756881AbdLOQpN (ORCPT + 24 others); Fri, 15 Dec 2017 11:45:13 -0500 Received: from mail-it0-f67.google.com ([209.85.214.67]:41542 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756767AbdLOQpI (ORCPT ); Fri, 15 Dec 2017 11:45:08 -0500 Received: by mail-it0-f67.google.com with SMTP id x28so21018109ita.0 for ; Fri, 15 Dec 2017 08:45:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nkJelSPBDg8JpR3T3TGdMqNYqX3NjJTFOmXPdYxFTc8=; b=KtQPtlFqSPKoR69gSqy3bwjnJWS9zoeHdEFqw+nipNyR7qxTcOnfd1N2+ha6fQcxal vS4QExuvpykRAdZhyE5dZBpVIhtn/xYU9Q0/iCKg6q8R6P5DHEeL4YAdWNgW4wEkLXd4 I9Wf0CxV8vJsJMkJk8N+AD7NpL9bLldCcKCDI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nkJelSPBDg8JpR3T3TGdMqNYqX3NjJTFOmXPdYxFTc8=; b=ko8sC4jmabHaY1KSENlk1lT6/dQ4DlH+h+XUR6ixB0FnegRqZHCGja28Dl/LuIqhTd 8fnws2+S/JvQLY/JfPKGKrL2FvqDdTpjEJZ+w4IDnU1A7piba370sqyWJOHfDVkloEPs ZJhWudB3Ek75C+HsQveFS1f82jIKEjYFecUxFaWeuenpX7ueV1OesOyQ3ZOsZun6Yfyu UXpPPbvFS2LL/euScxHYjc0+AUlLHJ9A8I7Loo43j8j1irsXjbHZHn8gwFIYNS+ZBlYs Q/dzpOjsQVbL5jhMB/0aeQ2CGPwA0Pq3trA4f+OApmeR1A64DV6g+4TVnIWV87lazI9B Iivw== X-Gm-Message-State: AKGB3mJlSqaVOYbIjaHaXr4fObPFS6OLdDaxRFwUrt1cHu2eonTxo6JS Q4CviAY4idi8np+dANP+E1npRQ== X-Received: by 10.36.227.3 with SMTP id d3mr9106493ith.47.1513356307669; Fri, 15 Dec 2017 08:45:07 -0800 (PST) Received: from xps15.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [68.147.8.254]) by smtp.gmail.com with ESMTPSA id q132sm3631732iod.26.2017.12.15.08.45.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 15 Dec 2017 08:45:06 -0800 (PST) From: Mathieu Poirier To: acme@kernel.org Cc: peterz@infradead.org, mingo@redhat.com, alexander.shishkin@linux.intel.com, namhyung@kernel.org, adrian.hunter@intel.com, mike.leach@arm.com, suzuki.poulosi@arm.com, tor@ti.com, jolsa@redhat.com, mathieu.poirier@linaro.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 02/10] perf tools: Add initial entry point for decoder CoreSight traces Date: Fri, 15 Dec 2017 09:44:51 -0700 Message-Id: <1513356299-26274-3-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513356299-26274-1-git-send-email-mathieu.poirier@linaro.org> References: <1513356299-26274-1-git-send-email-mathieu.poirier@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds the entry point for CoreSight trace decoding, serving as a jumping board for furhter expansions. Co-authored-by: Tor Jeremiassen Signed-off-by: Mathieu Poirier --- tools/perf/util/Build | 5 ++ tools/perf/util/auxtrace.c | 2 + tools/perf/util/cs-etm.c | 213 +++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/cs-etm.h | 15 ++++ 4 files changed, 235 insertions(+) create mode 100644 tools/perf/util/cs-etm.c -- 2.7.4 diff --git a/tools/perf/util/Build b/tools/perf/util/Build index a3de7916fe63..49d447ca8644 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -86,6 +86,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 CONFIG_LIBOPENCSD +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 a33491416400..d07e31bd6120 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -55,6 +55,7 @@ #include "debug.h" #include +#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: + return cs_etm__process_auxtrace_info(event, session); case PERF_AUXTRACE_UNKNOWN: default: return -EINVAL; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c new file mode 100644 index 000000000000..f47797101857 --- /dev/null +++ b/tools/perf/util/cs-etm.c @@ -0,0 +1,213 @@ +/* + * SPDX-License-Identifier: GPL-2.0 + * + * Copyright(C) 2015-2018 Linaro Limited. + * + * Author: Tor Jeremiassen + * Author: Mathieu Poirier + */ + +#include +#include +#include +#include +#include + +#include + +#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; +} diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index 3cc6bc3263fe..5ab6a8ef1b32 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,16 @@ 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 __maybe_unused, + struct perf_session *session __maybe_unused) +{ + return -1; +} +#endif + #endif