From patchwork Tue Jan 23 13:12:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaldo Carvalho de Melo X-Patchwork-Id: 125515 Delivered-To: patch@linaro.org Received: by 10.46.66.141 with SMTP id h13csp1750507ljf; Tue, 23 Jan 2018 05:16:59 -0800 (PST) X-Google-Smtp-Source: AH8x226BlXDgftoT+y4kzQJS74xEkDqf3JNMouUAj5dwiCaqceR4t6ur5XdwgVbwMCTNnvPOjdLt X-Received: by 10.99.113.67 with SMTP id b3mr4639737pgn.134.1516713419289; Tue, 23 Jan 2018 05:16:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516713419; cv=none; d=google.com; s=arc-20160816; b=XuMHYevufRRIPSMSgT7M6n5qLyf28TlQSpKdwZv0hoPkQIRe1I2IOvqyF2cGySGs2C YzZ7zRhOO7bfMAul7wLTqa7RW7XXc747HEqaCaer6nb7SXI21me8KacK6wxV+GL0SwCH hJTOkUJz9F7R5ki8+zRn7Edg7ErpMPpOWIWpaiAoomYvNwqJaVe4+UtEDtU4bteWFF8v 12Y9zOQpFTcTMa7fJm7lWVYdPiapm9Ul1NfBHTXKKJQYG2FKfZ1i/UEWSXKmVyIipZcy leTe3HNbI26m4cAZZkHCmNmviwfiB2nFqnOVpTA+5TvhKSB45nzav5CPNSxoWai18OzX Kr4A== 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:dmarc-filter:arc-authentication-results; bh=13CSZpeocbfLwd7YSiL2BBL+fDtRfB7ttW2BCk8eD9I=; b=ndpH5pxar2jqGQcuFgkQsOZz4DJqZfN8IVdJqvcXa/+wEzNtK7DeYdE9Y+LXT59jxu v2R8QkzBzt5P66UBWqp6WN8CPAiJd1lD9vDpN2f6ow5tCcOivj7ausvPuZdvBJv/WZGp reYzFa7W+yGFfm7Kc80WlqpEQBkh8LzzT06dB3sXN+s4e1C9xmYrYiJtlRoXutBOHB3a fbX9hW7+aXHeKAuHt8cikEGe9fkukdZ1jKUbMkkVlKstCRkawcqUDdp7U8TOBE28v+vn 0KgQvXL3flJeOMM2JhTakPsL6gQ3OH6mrw0TgEfOftaEy5b2RYMFmLvHjUAd2G/ld5ui NjOg== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f20-v6si4732586plj.727.2018.01.23.05.16.59; Tue, 23 Jan 2018 05:16:59 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752530AbeAWNQ6 (ORCPT + 28 others); Tue, 23 Jan 2018 08:16:58 -0500 Received: from mail.kernel.org ([198.145.29.99]:47356 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752273AbeAWNOY (ORCPT ); Tue, 23 Jan 2018 08:14:24 -0500 Received: from jouet.infradead.org (unknown [179.97.41.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 9D2B62178F; Tue, 23 Jan 2018 13:14:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9D2B62178F Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=acme@kernel.org From: Arnaldo Carvalho de Melo To: Ingo Molnar Cc: linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Mathieu Poirier , Adrian Hunter , Alexander Shishkin , Kim Phillips , Mike Leach , Namhyung Kim , Peter Zijlstra , Suzuki Poulouse , linux-arm-kernel@lists.infradead.org, Arnaldo Carvalho de Melo Subject: [PATCH 34/43] pert tools: Add queue management functionality Date: Tue, 23 Jan 2018 10:12:42 -0300 Message-Id: <20180123131251.28197-35-acme@kernel.org> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180123131251.28197-1-acme@kernel.org> References: <20180123131251.28197-1-acme@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mathieu Poirier Add functionatlity to setup trace queues so that traces associated with CoreSight auxtrace events found in the perf.data file can be classified properly. The decoder and memory callback associated with each queue are then used to decode the traces that have been assigned to that queue. Co-authored-by: Tor Jeremiassen Signed-off-by: Mathieu Poirier Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Kim Phillips Cc: Mike Leach Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Suzuki Poulouse Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1516211539-5166-8-git-send-email-mathieu.poirier@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cs-etm.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 204 insertions(+), 4 deletions(-) -- 2.14.3 diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index cad429ce3c00..83eb676274b5 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -196,15 +196,215 @@ static void cs_etm__free(struct perf_session *session) zfree(&aux); } +static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u64 address, + size_t size, u8 *buffer) +{ + u8 cpumode; + u64 offset; + int len; + struct thread *thread; + struct machine *machine; + struct addr_location al; + + if (!etmq) + return -1; + + machine = etmq->etm->machine; + if (address >= etmq->etm->kernel_start) + cpumode = PERF_RECORD_MISC_KERNEL; + else + cpumode = PERF_RECORD_MISC_USER; + + thread = etmq->thread; + if (!thread) { + if (cpumode != PERF_RECORD_MISC_KERNEL) + return -EINVAL; + thread = etmq->etm->unknown_thread; + } + + thread__find_addr_map(thread, cpumode, MAP__FUNCTION, address, &al); + + if (!al.map || !al.map->dso) + return 0; + + if (al.map->dso->data.status == DSO_DATA_STATUS_ERROR && + dso__data_status_seen(al.map->dso, DSO_DATA_STATUS_SEEN_ITRACE)) + return 0; + + offset = al.map->map_ip(al.map, address); + + map__load(al.map); + + len = dso__data_read_offset(al.map->dso, machine, offset, buffer, size); + + if (len <= 0) + return 0; + + return len; +} + +static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *etm, + unsigned int queue_nr) +{ + int i; + struct cs_etm_decoder_params d_params; + struct cs_etm_trace_params *t_params; + struct cs_etm_queue *etmq; + + etmq = zalloc(sizeof(*etmq)); + if (!etmq) + return NULL; + + etmq->event_buf = malloc(PERF_SAMPLE_MAX_SIZE); + if (!etmq->event_buf) + goto out_free; + + etmq->etm = etm; + etmq->queue_nr = queue_nr; + etmq->pid = -1; + etmq->tid = -1; + etmq->cpu = -1; + + /* Use metadata to fill in trace parameters for trace decoder */ + t_params = zalloc(sizeof(*t_params) * etm->num_cpu); + + if (!t_params) + goto out_free; + + for (i = 0; i < etm->num_cpu; i++) { + t_params[i].protocol = CS_ETM_PROTO_ETMV4i; + t_params[i].etmv4.reg_idr0 = etm->metadata[i][CS_ETMV4_TRCIDR0]; + t_params[i].etmv4.reg_idr1 = etm->metadata[i][CS_ETMV4_TRCIDR1]; + t_params[i].etmv4.reg_idr2 = etm->metadata[i][CS_ETMV4_TRCIDR2]; + t_params[i].etmv4.reg_idr8 = etm->metadata[i][CS_ETMV4_TRCIDR8]; + t_params[i].etmv4.reg_configr = + etm->metadata[i][CS_ETMV4_TRCCONFIGR]; + t_params[i].etmv4.reg_traceidr = + etm->metadata[i][CS_ETMV4_TRCTRACEIDR]; + } + + /* Set decoder parameters to simply print the trace packets */ + d_params.packet_printer = cs_etm__packet_dump; + d_params.operation = CS_ETM_OPERATION_DECODE; + d_params.formatted = true; + d_params.fsyncs = false; + d_params.hsyncs = false; + d_params.frame_aligned = true; + d_params.data = etmq; + + etmq->decoder = cs_etm_decoder__new(etm->num_cpu, &d_params, t_params); + + zfree(&t_params); + + if (!etmq->decoder) + goto out_free; + + /* + * Register a function to handle all memory accesses required by + * the trace decoder library. + */ + if (cs_etm_decoder__add_mem_access_cb(etmq->decoder, + 0x0L, ((u64) -1L), + cs_etm__mem_access)) + goto out_free_decoder; + + etmq->offset = 0; + + return etmq; + +out_free_decoder: + cs_etm_decoder__free(etmq->decoder); +out_free: + zfree(&etmq->event_buf); + free(etmq); + + return NULL; +} + +static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm, + struct auxtrace_queue *queue, + unsigned int queue_nr) +{ + struct cs_etm_queue *etmq = queue->priv; + + if (list_empty(&queue->head) || etmq) + return 0; + + etmq = cs_etm__alloc_queue(etm, queue_nr); + + if (!etmq) + return -ENOMEM; + + queue->priv = etmq; + + if (queue->cpu != -1) + etmq->cpu = queue->cpu; + + etmq->tid = queue->tid; + + return 0; +} + +static int cs_etm__setup_queues(struct cs_etm_auxtrace *etm) +{ + unsigned int i; + int ret; + + for (i = 0; i < etm->queues.nr_queues; i++) { + ret = cs_etm__setup_queue(etm, &etm->queues.queue_array[i], i); + if (ret) + return ret; + } + + return 0; +} + +static int cs_etm__update_queues(struct cs_etm_auxtrace *etm) +{ + if (etm->queues.new_data) { + etm->queues.new_data = false; + return cs_etm__setup_queues(etm); + } + + return 0; +} + 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; + int err = 0; + u64 timestamp; + struct cs_etm_auxtrace *etm = container_of(session->auxtrace, + struct cs_etm_auxtrace, + auxtrace); + + /* Keep compiler happy */ + (void)event; + + if (dump_trace) + return 0; + + if (!tool->ordered_events) { + pr_err("CoreSight ETM Trace requires ordered events\n"); + return -EINVAL; + } + + if (!etm->timeless_decoding) + return -EINVAL; + + if (sample->time && (sample->time != (u64) -1)) + timestamp = sample->time; + else + timestamp = 0; + + if (timestamp || etm->timeless_decoding) { + err = cs_etm__update_queues(etm); + if (err) + return err; + } + return 0; }