Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Leo Yan <leo.yan@arm.com>
To: Suzuki K Poulose <suzuki.poulose@arm.com>,
	 Mike Leach <mike.leach@arm.com>,
	James Clark <james.clark@linaro.org>,
	 Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	 Anshuman Khandual <anshuman.khandual@arm.com>,
	 Tamas Petz <tamas.petz@arm.com>,
	Tamas Zsoldos <tamas.zsoldos@arm.com>,
	 Suyash Mahar <smahar@meta.com>, Amir Ayupov <aaupov@fb.com>
Cc: linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,  coresight@lists.linaro.org,
	Leo Yan <leo.yan@arm.com>
Subject: [PATCH v2 08/11] perf cs-etm: Reset decoder on COLLISION flag
Date: Fri, 16 Oct 2026 22:11:46 +0100	[thread overview]
Message-ID: <20261016-trbe_buffer_refactor_v2-v2-8-383ac26382fa@arm.com> (raw)
In-Reply-To: <20261016-trbe_buffer_refactor_v2-v2-0-383ac26382fa@arm.com>

Resetting the decoder at every AUX fragment boundary can discard pending
decode state even when the trace stream is continuous.

Store AUX flags when queuing indexed fragments. Preserve decoder state
across their boundaries and request an explicit reset for the next block
when the current fragment reports PERF_AUX_FLAG_COLLISION. Source restarts
with in-band synchronization are handled by the decoder. Keep resetting
between blocks queued without AUX records, where the flags are unavailable.

Keep setting and clearing the queue reset flag in cs_etm__get_trace(),
where the preceding fragment is available. Clear a request after its
nonempty block has been consumed and derive collision resets from that
fragment. Preserve deferred requests through empty buffers.
cs_etm__get_data_block() only performs the requested reset before
processing the fetched block.

Keep flushing retained context-ID thread stacks at every data block
boundary. AUX records do not distinguish buffer maintenance from normal
event disable/re-enable. In-band restart packets synchronize the decoder,
but only the current thread's stack is flushed when processing a
discontinuity. Another thread may have changed its stack while tracing was
disabled, and its first instruction sample after restart can otherwise
contain stale return addresses before branch bookkeeping clears the stack.

Flush those stacks before decoding the new block. This conservatively
limits callchains and branch history to each chunk while preserving decoder
continuity. Improving stack continuity can be handled separately.

Signed-off-by: Leo Yan <leo.yan@arm.com>
---
 tools/perf/util/auxtrace.h |  2 ++
 tools/perf/util/cs-etm.c   | 46 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 6947f3f284c029286837e4e1dd9f535a5f0b6334..6ea212802e418ebd6536e3ea5456bab7530eeb26 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -243,6 +243,7 @@ struct auxtrace {
  * @buffer_nr: used to number each buffer
  * @use_size: implementation actually only uses this number of bytes
  * @use_data: implementation actually only uses data starting at this address
+ * @aux_flags: AUX event flags
  */
 struct auxtrace_buffer {
 	struct list_head	list;
@@ -261,6 +262,7 @@ struct auxtrace_buffer {
 	u64			buffer_nr;
 	size_t			use_size;
 	void			*use_data;
+	u64			aux_flags;
 };
 
 /**
diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c
index 114b3cd2da495e54e78df8fbd707898312f95079..6f95730fe3b94ae3f534eee505132a2efbc4ff96 100644
--- a/tools/perf/util/cs-etm.c
+++ b/tools/perf/util/cs-etm.c
@@ -136,6 +136,9 @@ struct cs_etm_queue {
 	 */
 	struct intlist *own_traceid_list;
 	u32 sink_id;
+
+	/* Reset decoder before processing the fetched data block. */
+	bool reset_decoder;
 };
 
 static int cs_etm__process_timestamped_queues(struct cs_etm_auxtrace *etm);
@@ -1436,6 +1439,13 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
 	struct auxtrace_buffer *old_buffer = aux_buffer;
 	struct auxtrace_queue *queue;
 
+	/*
+	 * Clear the reset request for the consumed block. Empty buffers have
+	 * no decoded bytes, so preserve requests deferred through them.
+	 */
+	if (etmq->buf_used)
+		etmq->reset_decoder = false;
+
 	queue = &etmq->etm->queues.queue_array[etmq->queue_nr];
 
 	aux_buffer = auxtrace_buffer__next(queue, aux_buffer);
@@ -1467,6 +1477,15 @@ cs_etm__get_trace(struct cs_etm_queue *etmq)
 	etmq->buf_used = 0;
 	etmq->buf_len = aux_buffer->size;
 	etmq->buf = aux_buffer->data;
+
+	/*
+	 * A collision requires a reset after its fragment. Without AUX flags,
+	 * reset between all blocks.
+	 */
+	if (old_buffer && (!etmq->etm->data_queued ||
+			   (old_buffer->aux_flags & PERF_AUX_FLAG_COLLISION)))
+		etmq->reset_decoder = true;
+
 	return 0;
 }
 
@@ -2162,17 +2181,15 @@ static int cs_etm__get_data_block(struct cs_etm_queue *etmq)
 	if (!etmq->buf_len)
 		return 0;
 
-	/*
-	 * We cannot assume consecutive blocks in the data file
-	 * are contiguous, reset the decoder to force re-sync.
-	 */
-	ret = cs_etm_decoder__reset(etmq->decoder);
-	if (ret)
-		return ret;
+	if (etmq->reset_decoder) {
+		ret = cs_etm_decoder__reset(etmq->decoder);
+		if (ret)
+			return ret;
+	}
 
 	/*
-	 * Since the decoder is reset, this causes a global trace
-	 * discontinuity. Flush all thread stacks.
+	 * AUX records do not distinguish buffer maintenance from a source
+	 * restart. Flush all thread stacks before sampling the new block.
 	 */
 	cs_etm__flush_all_stack(etmq);
 
@@ -3154,9 +3171,8 @@ static u64 *cs_etm__create_meta_blk(u64 *buff_in, int *buff_in_offset,
  * file_offset.
  *
  * Normally, whole auxtrace buffers would be added to the queue. But we
- * want to reset the decoder for every PERF_RECORD_AUX event, and the decoder
- * is reset across each buffer, so splitting the buffers up in advance has
- * the same effect.
+ * want to check every PERF_RECORD_AUX event to decide if need to reset
+ * decoder across each buffer, so splitting the buffers up in advance.
  */
 static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_offset, size_t sz,
 				      struct perf_record_aux *aux_event, struct perf_sample *sample)
@@ -3168,6 +3184,7 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o
 	union perf_event auxtrace_fragment;
 	__u64 aux_offset, aux_size;
 	enum cs_etm_format format;
+	struct auxtrace_buffer *buffer = NULL;
 
 	struct cs_etm_auxtrace *etm = container_of(session->auxtrace,
 						   struct cs_etm_auxtrace,
@@ -3251,10 +3268,13 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o
 		pr_debug3("CS ETM: Queue buffer size: %#"PRI_lx64" offset: %#"PRI_lx64
 			  " tid: %d cpu: %d\n", aux_size, aux_offset, sample->tid, sample->cpu);
 		err = auxtrace_queues__add_event(&etm->queues, session, &auxtrace_fragment,
-						 file_offset, NULL);
+						 file_offset, &buffer);
 		if (err)
 			return err;
 
+		if (buffer)
+			buffer->aux_flags = aux_event->flags;
+
 		format = (aux_event->flags & PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW) ?
 				UNFORMATTED : FORMATTED;
 		if (etmq->format != UNSET && format != etmq->format) {

-- 
2.34.1



  parent reply	other threads:[~2026-10-16 21:12 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 21:11 [PATCH v2 00/11] coresight: trbe: Refactor buffer handling and add trigger support Leo Yan
2026-10-16 21:11 ` [PATCH v2 01/11] coresight: trbe: Remove misleading comment Leo Yan
2026-10-16 21:11 ` [PATCH v2 02/11] coresight: trbe: Refactor next buffer computation Leo Yan
2026-10-16 21:11 ` [PATCH v2 03/11] coresight: trbe: Track trigger count support per CPU Leo Yan
2026-10-16 21:11 ` [PATCH v2 04/11] coresight: trbe: Use trigger mode for buffer maintenance Leo Yan
2026-10-16 21:11 ` [PATCH v2 05/11] coresight: trbe: Leave headroom for stop-on-trigger mode Leo Yan
2026-10-16 21:11 ` [PATCH v2 06/11] coresight: trbe: Save and restore trigger counter Leo Yan
2026-10-16 21:11 ` [PATCH v2 07/11] coresight: trbe: Add KUnit tests for compute normal buffer Leo Yan
2026-10-16 21:11 ` Leo Yan [this message]
2026-10-16 21:11 ` [PATCH v2 09/11] perf cs-etm: Reset per-thread decoder on CPU migration Leo Yan
2026-10-16 21:11 ` [PATCH v2 10/11] perf cs-etm: Reset decoder on AUX offset discontinuity Leo Yan
2026-10-16 21:11 ` [PATCH v2 11/11] perf cs-etm: Set watermark for AUX trace Leo Yan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261016-trbe_buffer_refactor_v2-v2-8-383ac26382fa@arm.com \
    --to=leo.yan@arm.com \
    --cc=aaupov@fb.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=anshuman.khandual@arm.com \
    --cc=coresight@lists.linaro.org \
    --cc=james.clark@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mike.leach@arm.com \
    --cc=smahar@meta.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tamas.petz@arm.com \
    --cc=tamas.zsoldos@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox