From nobody Tue Feb 10 05:17:19 2026 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F97115B546 for ; Fri, 12 Jul 2024 10:22:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720779738; cv=none; b=jKZndOGX6LKyQmrw1qNcpM846ieMgRIqspwoMaBYqVn6NBzB5hb8UG5uYNmWlreR5z+VIlBbj9xB13XEz+2XI2znSRlb2JVR+H6N5PElEfr4RpZXcCsCG/ZWIsUHc/0z2fJ7J4IWcD3YI4oGQGH/4Z68U6ZLRei3MlllGBsLpaA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1720779738; c=relaxed/simple; bh=o4TLkDUQM2jPHQGaB2ChCXge2O12uDzAcClw0+3s8Oo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JroFwXAmX4rdjCoTtlJ+tI2gOGhOWr/PS+EX3935libi2Dv0pTYKJ0ilBiLmX1SOC80r1SsI/8iYQceQBcW+0T1T6vFJrAZ6KlH0a9pCKluLjFkzocZE9RVRsrGw3SBB7kMKWFrWDH9gIM4eQdgpLrinYfvgOut+OxlGCzjkp48= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=Wqol0+mG; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Wqol0+mG" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-367a3d1a378so1529417f8f.1 for ; Fri, 12 Jul 2024 03:22:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1720779735; x=1721384535; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MNTcw4AodgvALwpMsLXckWgH/elRtcEkEFuXm1R3qd8=; b=Wqol0+mGNDcOju+/1wX41bKSmyWdGj5t7BN85Eq7QzkianIHXcavk5gF3Upj/NOtGi 55VikmQdiRCOepk0DBcOkcCgTBmzuvMB89IQFeRRQaDBU0tkoCHdgXTahKzEoNZR34g7 /p3BJXUW4Zxp7qjXr8JVS3JPEgciwNRASKSxm/eBs+FidWPE9qDfrhaeRepku8MOTh5S WVPcfdnI2UtlJ6uyhFPYzg4vB5P3nqtL6eYtHhviVPp93GSFaK19mWBkQxcMwdWh1L0p 6urLlKUvLHv7TvviqdDrBJ8p8jgR6yTm/gghsj0oi+m9lVztr8d8E08y3ptBA5Ruk1IC ftTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720779735; x=1721384535; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MNTcw4AodgvALwpMsLXckWgH/elRtcEkEFuXm1R3qd8=; b=IleDS1qOhv2CHlqC+lXqYL4kcZ/27rHuT61iB7MlAKG0kp+5Xnh6mV2ox8JSzHkUPq RxduHJPKdoMiDAFCZFNUqUL6GAUKPTqwZJ8fQIw7nWO/xuzRR90NCMhPXgpraMPcIgoe fPMcRVg+ktzLo4GFS1tWiFeHHoZYEA1y+YiiLcEIfmTf3oqyNJbXxqnG1a4caWzIGJN1 OBsQMvKlRA4T/Ysmx+n9MSv5SdM32820A7W7WvxNUPCaOctfDP7u83JdeJV83SN7HkT1 3XEqrRerZIHmBBcqSbgf+daFuP0i8MvM125khpNoiyQnKPUAenSoH0/Xd0yz+v+scgUt US/Q== X-Forwarded-Encrypted: i=1; AJvYcCVhmh7Nrk8Igk5eDHL2FnuaBx/EZ7pyDpaq8mWP3XFEXu+gL0BFhR4wyONDKjU1iyrvIK9oEgs9Ldj+Q4xGRq5TVg1sPcTFjemtgyo3 X-Gm-Message-State: AOJu0Ywgx5PIrjkaXikraNLub8Ia1gHC4NvtWDp72w7aG0Kscnpf6tdL hb/WEJ290WSR+LRjv/3Fl6t8SAszW+D4PmTZ9GadT6fD7zI2dkrBrjynpBNVZIs= X-Google-Smtp-Source: AGHT+IE5jKQ77NknrR1XwjZL3fqsubIZUggpAAhD4zFlsuEcwxOSOWIRp0kfpWgaR1ofOTl5hlff2g== X-Received: by 2002:a5d:4e46:0:b0:367:8ff5:5870 with SMTP id ffacd0b85a97d-367cead15f4mr7970265f8f.47.1720779734955; Fri, 12 Jul 2024 03:22:14 -0700 (PDT) Received: from localhost.localdomain ([89.47.253.130]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cde89164sm9911058f8f.63.2024.07.12.03.22.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Jul 2024 03:22:14 -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 , James Clark , Alexander Shishkin , Maxime Coquelin , Alexandre Torgue , John Garry , Will Deacon , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com, linux-perf-users@vger.kernel.org Subject: [PATCH v5 01/17] perf: cs-etm: Create decoders after both AUX and HW_ID search passes Date: Fri, 12 Jul 2024 11:20:10 +0100 Message-Id: <20240712102029.3697965-2-james.clark@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240712102029.3697965-1-james.clark@linaro.org> References: <20240712102029.3697965-1-james.clark@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Clark Both of these passes gather information about how to create the decoders. AUX records determine formatted/unformatted, and the HW_IDs determine the traceID/metadata mappings. Therefore it makes sense to cache the information and wait until both passes are over until creating the decoders, rather than creating them at the first HW_ID found. This will allow a simplification of the creation process where cs_etm_queue->traceid_list will exclusively used to create the decoders, rather than the current two methods depending on whether the trace is formatted or not. Previously the sample CPU from the AUX record was used to initialize the decoder CPU, but actually sample CPU =3D=3D AUX queue index in per-CPU mode, so saving the sample CPU isn't required. Similarly formatted/unformatted was used upfront to create the decoders, but now it's cached until later. Signed-off-by: James Clark Signed-off-by: James Clark Reviewed-by: Mike Leach --- tools/perf/util/cs-etm.c | 167 ++++++++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 65 deletions(-) diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 32818bd7cd17..f09004c4ba44 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -103,6 +103,7 @@ struct cs_etm_queue { struct auxtrace_buffer *buffer; unsigned int queue_nr; u8 pending_timestamp_chan_id; + bool formatted; u64 offset; const unsigned char *buf; size_t buf_len, buf_used; @@ -738,8 +739,7 @@ static int cs_etm__init_trace_params(struct cs_etm_trac= e_params *t_params, =20 static int cs_etm__init_decoder_params(struct cs_etm_decoder_params *d_par= ams, struct cs_etm_queue *etmq, - enum cs_etm_decoder_operation mode, - bool formatted) + enum cs_etm_decoder_operation mode) { int ret =3D -EINVAL; =20 @@ -749,7 +749,7 @@ static int cs_etm__init_decoder_params(struct cs_etm_de= coder_params *d_params, d_params->packet_printer =3D cs_etm__packet_dump; d_params->operation =3D mode; d_params->data =3D etmq; - d_params->formatted =3D formatted; + d_params->formatted =3D etmq->formatted; d_params->fsyncs =3D false; d_params->hsyncs =3D false; d_params->frame_aligned =3D true; @@ -1041,81 +1041,34 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *= etmq, u8 trace_chan_id, return ret; } =20 -static struct cs_etm_queue *cs_etm__alloc_queue(struct cs_etm_auxtrace *et= m, - bool formatted, int sample_cpu) +static struct cs_etm_queue *cs_etm__alloc_queue(void) { - struct cs_etm_decoder_params d_params; - struct cs_etm_trace_params *t_params =3D NULL; - struct cs_etm_queue *etmq; - /* - * Each queue can only contain data from one CPU when unformatted, so onl= y one decoder is - * needed. - */ - int decoders =3D formatted ? etm->num_cpu : 1; - - etmq =3D zalloc(sizeof(*etmq)); + struct cs_etm_queue *etmq =3D zalloc(sizeof(*etmq)); if (!etmq) return NULL; =20 etmq->traceid_queues_list =3D intlist__new(NULL); if (!etmq->traceid_queues_list) - goto out_free; - - /* Use metadata to fill in trace parameters for trace decoder */ - t_params =3D zalloc(sizeof(*t_params) * decoders); + free(etmq); =20 - if (!t_params) - goto out_free; - - if (cs_etm__init_trace_params(t_params, etm, formatted, sample_cpu, decod= ers)) - goto out_free; - - /* Set decoder parameters to decode trace packets */ - if (cs_etm__init_decoder_params(&d_params, etmq, - dump_trace ? CS_ETM_OPERATION_PRINT : - CS_ETM_OPERATION_DECODE, - formatted)) - goto out_free; - - etmq->decoder =3D cs_etm_decoder__new(decoders, &d_params, - 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; - - zfree(&t_params); return etmq; - -out_free_decoder: - cs_etm_decoder__free(etmq->decoder); -out_free: - intlist__delete(etmq->traceid_queues_list); - free(etmq); - - return NULL; } =20 static int cs_etm__setup_queue(struct cs_etm_auxtrace *etm, struct auxtrace_queue *queue, - unsigned int queue_nr, - bool formatted, - int sample_cpu) + unsigned int queue_nr, bool formatted) { struct cs_etm_queue *etmq =3D queue->priv; =20 + if (etmq && formatted !=3D etmq->formatted) { + pr_err("CS_ETM: mixed formatted and unformatted trace not supported\n"); + return -EINVAL; + } + if (list_empty(&queue->head) || etmq) return 0; =20 - etmq =3D cs_etm__alloc_queue(etm, formatted, sample_cpu); + etmq =3D cs_etm__alloc_queue(); =20 if (!etmq) return -ENOMEM; @@ -1123,7 +1076,9 @@ static int cs_etm__setup_queue(struct cs_etm_auxtrace= *etm, queue->priv =3D etmq; etmq->etm =3D etm; etmq->queue_nr =3D queue_nr; + queue->cpu =3D queue_nr; /* Placeholder, may be reset to -1 in per-thread= mode */ etmq->offset =3D 0; + etmq->formatted =3D formatted; =20 return 0; } @@ -2843,7 +2798,7 @@ static int cs_etm__process_auxtrace_event(struct perf= _session *session, * formatted in piped mode (true). */ err =3D cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], - idx, true, -1); + idx, true); if (err) return err; =20 @@ -3048,8 +3003,8 @@ static int cs_etm__queue_aux_fragment(struct perf_ses= sion *session, off_t file_o =20 idx =3D auxtrace_event->idx; formatted =3D !(aux_event->flags & PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW); - return cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], - idx, formatted, sample->cpu); + + return cs_etm__setup_queue(etm, &etm->queues.queue_array[idx], idx, form= atted); } =20 /* Wasn't inside this buffer, but there were no parse errors. 1 =3D=3D 'n= ot found' */ @@ -3233,6 +3188,84 @@ static int cs_etm__clear_unused_trace_ids_metadata(i= nt num_cpu, u64 **metadata) return 0; } =20 +/* + * Use the data gathered by the peeks for HW_ID (trace ID mappings) and AUX + * (formatted or not) packets to create the decoders. + */ +static int cs_etm__create_queue_decoders(struct cs_etm_queue *etmq) +{ + struct cs_etm_decoder_params d_params; + + /* + * Each queue can only contain data from one CPU when unformatted, so onl= y one decoder is + * needed. + */ + int decoders =3D etmq->formatted ? etmq->etm->num_cpu : 1; + + /* Use metadata to fill in trace parameters for trace decoder */ + struct cs_etm_trace_params *t_params =3D zalloc(sizeof(*t_params) * deco= ders); + + if (!t_params) + goto out_free; + + if (cs_etm__init_trace_params(t_params, etmq->etm, etmq->formatted, + etmq->queue_nr, decoders)) + goto out_free; + + /* Set decoder parameters to decode trace packets */ + if (cs_etm__init_decoder_params(&d_params, etmq, + dump_trace ? CS_ETM_OPERATION_PRINT : + CS_ETM_OPERATION_DECODE)) + goto out_free; + + etmq->decoder =3D cs_etm_decoder__new(decoders, &d_params, + 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; + + zfree(&t_params); + return 0; + +out_free_decoder: + cs_etm_decoder__free(etmq->decoder); +out_free: + zfree(&t_params); + return -EINVAL; +} + +static int cs_etm__create_decoders(struct cs_etm_auxtrace *etm) +{ + struct auxtrace_queues *queues =3D &etm->queues; + + for (unsigned int i =3D 0; i < queues->nr_queues; i++) { + bool empty =3D list_empty(&queues->queue_array[i].head); + struct cs_etm_queue *etmq =3D queues->queue_array[i].priv; + int ret; + + /* + * Don't create decoders for empty queues, mainly because + * etmq->formatted is unknown for empty queues. + */ + if (empty) + continue; + + ret =3D cs_etm__create_queue_decoders(etmq); + if (ret) + return ret; + } + return 0; +} + int cs_etm__process_auxtrace_info_full(union perf_event *event, struct perf_session *session) { @@ -3396,6 +3429,10 @@ int cs_etm__process_auxtrace_info_full(union perf_ev= ent *event, if (err) goto err_free_queues; =20 + err =3D cs_etm__queue_aux_records(session); + if (err) + goto err_free_queues; + /* * Map Trace ID values to CPU metadata. * @@ -3418,7 +3455,7 @@ int cs_etm__process_auxtrace_info_full(union perf_eve= nt *event, * flags if present. */ =20 - /* first scan for AUX_OUTPUT_HW_ID records to map trace ID values to CPU = metadata */ + /* Scan for AUX_OUTPUT_HW_ID records to map trace ID values to CPU metada= ta */ aux_hw_id_found =3D 0; err =3D perf_session__peek_events(session, session->header.data_offset, session->header.data_size, @@ -3436,7 +3473,7 @@ int cs_etm__process_auxtrace_info_full(union perf_eve= nt *event, if (err) goto err_free_queues; =20 - err =3D cs_etm__queue_aux_records(session); + err =3D cs_etm__create_decoders(etm); if (err) goto err_free_queues; =20 --=20 2.34.1