Received: by 2002:ab2:69cc:0:b0:1fd:c486:4f03 with SMTP id n12csp413213lqp; Tue, 11 Jun 2024 08:05:46 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCUO/8cPISPm2WsGiuzi6z1NGOHaTBT8r7O/LGFP7zGjU9hewsfkHMffg3X+CI6eEffTsXpiUbY4YWDyzgVWH6XjpTwjFYX2C8afGbPv/g== X-Google-Smtp-Source: AGHT+IFVaXd40+hTvtcMetedoRf0uexByyLGflOiueun5LIB6xV5uQYs6/m9SikzTnq4uNV2ZZyB X-Received: by 2002:a05:6102:3a10:b0:48c:3a9e:a9f6 with SMTP id ada2fe7eead31-48c3a9eaab7mr12853340137.11.1718118346221; Tue, 11 Jun 2024 08:05:46 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1718118346; cv=pass; d=google.com; s=arc-20160816; b=l+k5nya2umGYDBrZSb0WIFVZRVYIjrB25B7uvb3sUpBBQhp20SKS4dHadcVrYovpq2 AVQZprRGsErwFCFps30+iyszL3vNd5FI6zfZDv3ksUilP6F0l/SKpF3x2OXWQxwqjvWJ 53P+gAJhe6rXug7ML3asmNZ0LBBtkqhMolrSvyIAEmvzo97I1C6r6Czfioa5sOW91hlB I/q3LQmGZsZfpo02aNwrF/hf5lC6W8MZgQLt0BM+T9GWb0RE5c24e1XGRiUlwecuQ24X 691tX32RdygFMJNEIXyVhAvazfMHUXMrk4DgCk/PM1vfYnzIqi59wWsXsgoPPR1j5p9T 9i1g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=QQ/1C9bP4qo5aq8ztYItLr9muW1eBKq0zWNczLrjbqM=; fh=2s+eIsKHHam+jMV7/s2ffLwy54AhQ8M2v8jHKEN3Fe4=; b=kBn4jRyhzMz9E6eh9ot1tpauyf0W6jChhhJJEl58MhjPZRuYATsN+yVtoLXdRDtkHA vw+Wt0L17YPawQs5G4Il1RAmId5ycGEZtlYKEjO7tyxqGE4OdIx1AGw4lHK5In326CM7 /CiZjLq26TrstYcodhEZVZMRn9iwos7VvqKOk2VmqBSgaGhK8dFXZdig+ZliZAsHQY57 VcTRQdgZY4seHCjYGtjLr3W6JFuRKkBnebB5AkhY6deU6F7OXmdSUbm/b6SRGhH0/lQO 9jbxtpCxstG/987GDsQpY+wir1tteVhVCIsVVXP5l3rd5VNGDbeWVihQZq5OiO4UK2xS oWYA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-210116-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-210116-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id ada2fe7eead31-48c398a4007si1832745137.311.2024.06.11.08.05.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Jun 2024 08:05:46 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-210116-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-210116-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-210116-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id E9CC91C24A37 for ; Tue, 11 Jun 2024 15:04:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8498639FD0; Tue, 11 Jun 2024 15:03:13 +0000 (UTC) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0717423767; Tue, 11 Jun 2024 15:03:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718118192; cv=none; b=dRhOmgIT64u5qQ+askX1XQ7o76L9tdFJPIlG32r4eeMh2xp1fPjK9yFA+4C3d5e/t1jlG8RV157a6NQUbNQnB/pYuOzZBpm1Qfvz5PnzIwcKwOsWMGi0CNxMjbtOx+hlRGP2ipCwc6S8XrJGOWG/L9K/qNXENP1++ec4TvD8644= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718118192; c=relaxed/simple; bh=B4nm6nLK51aoQsLttd3Ekb+C8feSvY1WbvdomQFg9hE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=kqXEAt49oiMOAAmZB99VtX+zrctBNAFiWl609WVp/aow+9c9XHIAeRK19g66HbSlRnDqhhgbkU/BGXU4nquTWhsoJbg+HT6xJX8+M2HWZqqgc3wJvqTZRtnnPfhOgxXNVMDTahUBSS/4beQpxXORUEOyhUP4zduARWDc4fMIxbg= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 02027152B; Tue, 11 Jun 2024 08:03:34 -0700 (PDT) Received: from e127643.arm.com (unknown [10.57.41.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7E5E33F64C; Tue, 11 Jun 2024 08:03:05 -0700 (PDT) From: James Clark To: coresight@lists.linaro.org, suzuki.poulose@arm.com, gankulkarni@os.amperecomputing.com, mike.leach@linaro.org, leo.yan@linux.dev, anshuman.khandual@arm.com Cc: James Clark , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , John Garry , Will Deacon , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-perf-users@vger.kernel.org Subject: [PATCH v3 04/14] perf: cs-etm: Create decoders based on the trace ID mappings Date: Tue, 11 Jun 2024 16:02:15 +0100 Message-Id: <20240611150228.1802828-5-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240611150228.1802828-1-james.clark@arm.com> References: <20240611150228.1802828-1-james.clark@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Now that each queue has a unique set of trace ID mappings, use this list to create the decoders. This also works the same way for unformatted where a single dummy entry is added into the trace ID list. Previously each queue would have a decoder created for each traced CPU on the system but this won't work anymore because CPUs can have overlapping trace IDs. Signed-off-by: James Clark --- tools/perf/util/cs-etm.c | 143 +++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 58 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index be858aed26c4..73fc0ab2fb09 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -268,6 +268,10 @@ static int cs_etm__map_trace_id_v0(struct cs_etm_auxtrace *etm, u8 trace_chan_id int ret; struct cs_etm_queue *etmq = etm->queues.queue_array[i].priv; + /* Ignore HW_IDs on unformatted queues */ + if (etmq->formatted_set && !etmq->formatted) + continue; + ret = cs_etm__insert_trace_id_node(etmq, trace_chan_id, cpu_metadata); if (ret) @@ -673,80 +677,58 @@ static void cs_etm__packet_dump(const char *pkt_string) } static void cs_etm__set_trace_param_etmv3(struct cs_etm_trace_params *t_params, - struct cs_etm_auxtrace *etm, int t_idx, - int m_idx, u32 etmidr) + u64 *metadata, u32 etmidr) { - u64 **metadata = etm->metadata; - - t_params[t_idx].protocol = cs_etm__get_v7_protocol_version(etmidr); - t_params[t_idx].etmv3.reg_ctrl = metadata[m_idx][CS_ETM_ETMCR]; - t_params[t_idx].etmv3.reg_trc_id = metadata[m_idx][CS_ETM_ETMTRACEIDR]; + t_params->protocol = cs_etm__get_v7_protocol_version(etmidr); + t_params->etmv3.reg_ctrl = metadata[CS_ETM_ETMCR]; + t_params->etmv3.reg_trc_id = metadata[CS_ETM_ETMTRACEIDR]; } static void cs_etm__set_trace_param_etmv4(struct cs_etm_trace_params *t_params, - struct cs_etm_auxtrace *etm, int t_idx, - int m_idx) + u64 *metadata) { - u64 **metadata = etm->metadata; - - t_params[t_idx].protocol = CS_ETM_PROTO_ETMV4i; - t_params[t_idx].etmv4.reg_idr0 = metadata[m_idx][CS_ETMV4_TRCIDR0]; - t_params[t_idx].etmv4.reg_idr1 = metadata[m_idx][CS_ETMV4_TRCIDR1]; - t_params[t_idx].etmv4.reg_idr2 = metadata[m_idx][CS_ETMV4_TRCIDR2]; - t_params[t_idx].etmv4.reg_idr8 = metadata[m_idx][CS_ETMV4_TRCIDR8]; - t_params[t_idx].etmv4.reg_configr = metadata[m_idx][CS_ETMV4_TRCCONFIGR]; - t_params[t_idx].etmv4.reg_traceidr = metadata[m_idx][CS_ETMV4_TRCTRACEIDR]; + t_params->protocol = CS_ETM_PROTO_ETMV4i; + t_params->etmv4.reg_idr0 = metadata[CS_ETMV4_TRCIDR0]; + t_params->etmv4.reg_idr1 = metadata[CS_ETMV4_TRCIDR1]; + t_params->etmv4.reg_idr2 = metadata[CS_ETMV4_TRCIDR2]; + t_params->etmv4.reg_idr8 = metadata[CS_ETMV4_TRCIDR8]; + t_params->etmv4.reg_configr = metadata[CS_ETMV4_TRCCONFIGR]; + t_params->etmv4.reg_traceidr = metadata[CS_ETMV4_TRCTRACEIDR]; } static void cs_etm__set_trace_param_ete(struct cs_etm_trace_params *t_params, - struct cs_etm_auxtrace *etm, int t_idx, - int m_idx) + u64 *metadata) { - u64 **metadata = etm->metadata; - - t_params[t_idx].protocol = CS_ETM_PROTO_ETE; - t_params[t_idx].ete.reg_idr0 = metadata[m_idx][CS_ETE_TRCIDR0]; - t_params[t_idx].ete.reg_idr1 = metadata[m_idx][CS_ETE_TRCIDR1]; - t_params[t_idx].ete.reg_idr2 = metadata[m_idx][CS_ETE_TRCIDR2]; - t_params[t_idx].ete.reg_idr8 = metadata[m_idx][CS_ETE_TRCIDR8]; - t_params[t_idx].ete.reg_configr = metadata[m_idx][CS_ETE_TRCCONFIGR]; - t_params[t_idx].ete.reg_traceidr = metadata[m_idx][CS_ETE_TRCTRACEIDR]; - t_params[t_idx].ete.reg_devarch = metadata[m_idx][CS_ETE_TRCDEVARCH]; + t_params->protocol = CS_ETM_PROTO_ETE; + t_params->ete.reg_idr0 = metadata[CS_ETE_TRCIDR0]; + t_params->ete.reg_idr1 = metadata[CS_ETE_TRCIDR1]; + t_params->ete.reg_idr2 = metadata[CS_ETE_TRCIDR2]; + t_params->ete.reg_idr8 = metadata[CS_ETE_TRCIDR8]; + t_params->ete.reg_configr = metadata[CS_ETE_TRCCONFIGR]; + t_params->ete.reg_traceidr = metadata[CS_ETE_TRCTRACEIDR]; + t_params->ete.reg_devarch = metadata[CS_ETE_TRCDEVARCH]; } static int cs_etm__init_trace_params(struct cs_etm_trace_params *t_params, - struct cs_etm_auxtrace *etm, - bool formatted, - int sample_cpu, - int decoders) -{ - int t_idx, m_idx; - u32 etmidr; - u64 architecture; - - for (t_idx = 0; t_idx < decoders; t_idx++) { - if (formatted) - m_idx = t_idx; - else { - m_idx = get_cpu_data_idx(etm, sample_cpu); - if (m_idx == -1) { - pr_warning("CS_ETM: unknown CPU, falling back to first metadata\n"); - m_idx = 0; - } - } + struct cs_etm_queue *etmq) +{ + struct int_node *inode; - architecture = etm->metadata[m_idx][CS_ETM_MAGIC]; + intlist__for_each_entry(inode, etmq->traceid_list) { + u64 *metadata = inode->priv; + u64 architecture = metadata[CS_ETM_MAGIC]; + u32 etmidr; switch (architecture) { case __perf_cs_etmv3_magic: - etmidr = etm->metadata[m_idx][CS_ETM_ETMIDR]; - cs_etm__set_trace_param_etmv3(t_params, etm, t_idx, m_idx, etmidr); + etmidr = metadata[CS_ETM_ETMIDR]; + cs_etm__set_trace_param_etmv3(t_params++, metadata, etmidr); break; case __perf_cs_etmv4_magic: - cs_etm__set_trace_param_etmv4(t_params, etm, t_idx, m_idx); + cs_etm__set_trace_param_etmv4(t_params++, metadata); break; case __perf_cs_ete_magic: - cs_etm__set_trace_param_ete(t_params, etm, t_idx, m_idx); + cs_etm__set_trace_param_ete(t_params++, metadata); break; default: return -EINVAL; @@ -2918,6 +2900,42 @@ static u64 *cs_etm__create_meta_blk(u64 *buff_in, int *buff_in_offset, return metadata; } +/* + * traceid_list is used to create decoders and give them the trace ID + * mappings. In unformatted mode just insert one entry for the sample + * CPU so the decoder knows which settings to use. + */ +static int cs_etm__map_trace_ids_unformatted(struct cs_etm_auxtrace *etm) +{ + for (unsigned int i = 0; i < etm->queues.nr_queues; ++i) { + int ret; + struct cs_etm_queue *etmq; + u8 trace_chan_id; + u64 *cpu_data; + + etmq = etm->queues.queue_array[i].priv; + if (!etmq->formatted_set || etmq->formatted) + continue; + + /* Giving it a real ID doesn't do much but can help with debugging */ + trace_chan_id = CORESIGHT_LEGACY_CPU_TRACE_ID(i); + cpu_data = get_cpu_data(etm, i); + if (cpu_data == NULL) { + pr_warning("CS_ETM: unknown CPU, falling back to first metadata\n"); + cpu_data = etm->metadata[0]; + } + + ret = cs_etm__insert_trace_id_node(etmq, trace_chan_id, cpu_data); + if (ret) + return ret; + + ret = cs_etm__metadata_set_trace_id(trace_chan_id, cpu_data); + if (ret) + return ret; + } + return 0; +} + /** * Puts a fragment of an auxtrace buffer into the auxtrace queues based * on the bounds of aux_event, if it matches with the buffer that's at @@ -3220,21 +3238,26 @@ static int cs_etm__clear_unused_trace_ids_metadata(int num_cpu, u64 **metadata) static int cs_etm__create_queue_decoders(struct cs_etm_queue *etmq) { struct cs_etm_decoder_params d_params; + struct cs_etm_trace_params *t_params; + int decoders = intlist__nr_entries(etmq->traceid_list); /* * Each queue can only contain data from one CPU when unformatted, so only one decoder is * needed. */ - int decoders = etmq->formatted ? etmq->etm->num_cpu : 1; + if (etmq->formatted_set && !etmq->formatted) + assert(decoders == 1); + + if (decoders == 0) + return 0; /* Use metadata to fill in trace parameters for trace decoder */ - struct cs_etm_trace_params *t_params = zalloc(sizeof(*t_params) * decoders); + t_params = zalloc(sizeof(*t_params) * decoders); if (!t_params) goto out_free; - if (cs_etm__init_trace_params(t_params, etmq->etm, etmq->formatted, - etmq->queue_nr, decoders)) + if (cs_etm__init_trace_params(t_params, etmq)) goto out_free; /* Set decoder parameters to decode trace packets */ @@ -3497,6 +3520,10 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, if (err) goto err_free_queues; + err = cs_etm__map_trace_ids_unformatted(etm); + if (err) + goto err_free_queues; + err = cs_etm__create_decoders(etm); if (err) goto err_free_queues; -- 2.34.1