mirror of https://lore.kernel.org/lkml/
 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 22/23] coresight: trbe: Restart trace source for stopped buffers
Date: Fri, 16 Oct 2026 17:55:20 +0100	[thread overview]
Message-ID: <20261016-trbe_enable_disable_irq_handle_refactor-v2-22-3f57cf3199b1@arm.com> (raw)
In-Reply-To: <20261016-trbe_enable_disable_irq_handle_refactor-v2-0-3f57cf3199b1@arm.com>

When TRBSR reports a stopped buffer, the IRQ handler closes the current
AUX buffer and programs TRBE for the next run. This creates a trace
discontinuity. User tool has to reset the decoder when moving to the
next AUX data block, which can reduce decoded trace coverage.

Stop and restart the trace source around TRBE reprogramming for stopped
buffers. This emits ASYNC packets, allowing the decoder to recognize
discontinuity without a full reset.

This duplicates part of the trace source enable/disable code in the
ETMv4 driver. Reusing that code would require splitting the ETMv4
callbacks into finer-grained helpers that TRBE can call, which would
make the change much larger. Keep the TRBE change self-contained for
now.

Signed-off-by: Leo Yan <leo.yan@arm.com>
---
 drivers/hwtracing/coresight/coresight-trbe.c | 121 +++++++++++++++++++++++++--
 1 file changed, 116 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 36f143a15e680b28aa6ca6a43ad7d3ee134693be..6bc82d5b55539795059da37039d2929b4ea504e3 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -17,9 +17,11 @@
 
 #include <asm/barrier.h>
 #include <asm/cpufeature.h>
+#include <linux/iopoll.h>
 #include <linux/kvm_host.h>
 #include <linux/vmalloc.h>
 
+#include "coresight-etm4x.h"
 #include "coresight-self-hosted-trace.h"
 #include "coresight-trbe.h"
 
@@ -1132,14 +1134,106 @@ static void trbe_handle_spurious(struct trbe_cpudata *cpudata)
 	set_trbe_enabled(cpudata, trblimitr);
 }
 
+static u64 read_sys_trcstatr(void)
+{
+	/* Context synchronization for each polling */
+	isb();
+	return read_sysreg_s(SYS_TRCSTATR);
+}
+
+static int arm_trbe_start_tracer(u64 trcprgctlr)
+{
+	u64 val;
+
+	/* A pending IRQ after AUX pause? */
+	if (!(trcprgctlr & BIT(0)))
+		return 0;
+
+	/* Restore the saved tracer state */
+	write_sysreg_s(trcprgctlr, SYS_TRCPRGCTLR);
+
+	/*
+	 * Context synchronization between writing to the TRCPRGCTLR and
+	 * reading the TRCSTATR.
+	 */
+	isb();
+
+	/* Wait for TRCSTATR.IDLE to go down to 0 */
+	if (read_poll_timeout_atomic(read_sys_trcstatr, val,
+				     !(val & BIT(TRCSTATR_IDLE_BIT)),
+				     1,		/* delay_us */
+				     TIMEOUT_US, /* timeout_us */
+				     false)) {	/* delay_before_read */
+		pr_err("TRBE: timeout for TRCSTATR IDLE\n");
+		return -ETIME;
+	}
+
+	/* Context synchronization after programming the tracer */
+	isb();
+
+	return 0;
+}
+
+static int arm_trbe_stop_tracer(u64 *trcprgctlr)
+{
+	u64 val;
+
+	/* Disable tracer and save trcprgctlr */
+	*trcprgctlr = read_sysreg_s(SYS_TRCPRGCTLR);
+
+	/* No need to stop tracer again */
+	if (!(*trcprgctlr & BIT(0)))
+		return 0;
+
+	write_sysreg_s(*trcprgctlr & ~BIT(0), SYS_TRCPRGCTLR);
+
+	/*
+	 * Context synchronization between writing to the TRCPRGCTLR and
+	 * reading the TRCSTATR.
+	 */
+	isb();
+
+	/*
+	 * PMSTABLE alone does not permit re-enabling the tracer.
+	 * Wait for TRCSTATR.IDLE to go to 1.
+	 */
+	if (read_poll_timeout_atomic(read_sys_trcstatr, val,
+				     val & BIT(TRCSTATR_IDLE_BIT),
+				     1,
+				     TIMEOUT_US,
+				     false)) {
+		pr_err("TRBE: timeout for TRCSTATR IDLE=1\n");
+		return -ETIME;
+	}
+
+	/* Context synchronization after programming the tracer */
+	isb();
+
+	return 0;
+}
+
 static int trbe_handle_overflow(struct trbe_cpudata *cpudata,
-				enum trbe_fault_action act)
+				enum trbe_fault_action act,
+				bool is_buffer_stopped)
 {
 	struct perf_output_handle *handle = cpudata->handle;
 	struct perf_event *event = handle->event;
 	struct trbe_buf *buf = etm_perf_sink_config(handle);
 	unsigned long size;
 	struct etm_event_data *event_data;
+	u64 trcprgctlr = 0;
+	int ret = 0;
+
+	/*
+	 * Since the trace buffer has stopped, disable and re-enable the
+	 * tracer to generate ASYNC packets. This allows the decoder to
+	 * recognize the discontinuity in the trace stream.
+	 */
+	if (is_buffer_stopped) {
+		ret = arm_trbe_stop_tracer(&trcprgctlr);
+		if (ret)
+			goto truncate_event;
+	}
 
 	/*
 	 * Clear the status. No context synchronization is required here,
@@ -1172,11 +1266,27 @@ static int trbe_handle_overflow(struct trbe_cpudata *cpudata,
 	 */
 	buf = etm_perf_sink_config(handle);
 	if (!buf || buf->cpudata != cpudata) {
-		trbe_truncate_event(handle);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto truncate_event;
+	}
+
+	ret = __arm_trbe_enable(buf, handle);
+	if (ret)
+		return ret;
+
+	if (is_buffer_stopped) {
+		ret = arm_trbe_start_tracer(trcprgctlr);
+		if (ret) {
+			trbe_drain_and_disable_local(cpudata);
+			goto truncate_event;
+		}
 	}
 
-	return __arm_trbe_enable(buf, handle);
+	return 0;
+
+truncate_event:
+	trbe_truncate_event(handle);
+	return ret;
 }
 
 static bool is_perf_trbe(struct perf_output_handle *handle)
@@ -1267,7 +1377,8 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 	act = trbe_get_fault_act(handle, status);
 	switch (act) {
 	case TRBE_FAULT_ACT_WRAP:
-		truncated = !!trbe_handle_overflow(cpudata, act);
+		truncated = !!trbe_handle_overflow(cpudata, act,
+						   !is_trbe_running(status));
 		break;
 	case TRBE_FAULT_ACT_SPURIOUS:
 		trbe_handle_spurious(cpudata);

-- 
2.34.1


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

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 16:54 [PATCH v2 00/23] coresight: trbe: Refactor buffer and IRQ handling Leo Yan
2026-10-16 16:54 ` [PATCH v2 01/23] arm64/sysreg: Define TRBSR_EL1.EC event classes Leo Yan
2026-10-16 16:55 ` [PATCH v2 02/23] coresight: trbe: Make watermark range check overflow safe in __trbe_normal_offset() Leo Yan
2026-10-16 16:55 ` [PATCH v2 03/23] coresight: trbe: Use helpers for checking errata Leo Yan
2026-10-16 16:55 ` [PATCH v2 04/23] coresight: trbe: Check the buffer association before IRQ validation Leo Yan
2026-10-16 16:55 ` [PATCH v2 05/23] coresight: trbe: Validate perf handle before using sink data Leo Yan
2026-10-16 16:55 ` [PATCH v2 06/23] coresight: trbe: Drop redundant disable from enable path Leo Yan
2026-10-16 16:55 ` [PATCH v2 07/23] coresight: trbe: Publish the session after successful enable Leo Yan
2026-10-16 16:55 ` [PATCH v2 08/23] coresight: trbe: Clear stale external abort status Leo Yan
2026-10-16 16:55 ` [PATCH v2 09/23] coresight: trbe: Clear TRBSR status at stop sites Leo Yan
2026-10-16 16:55 ` [PATCH v2 10/23] coresight: trbe: Drop redundant disables Leo Yan
2026-10-16 16:55 ` [PATCH v2 11/23] coresight: trbe: Assign the perf handle in enable and disable Leo Yan
2026-10-16 16:55 ` [PATCH v2 12/23] coresight: trbe: Decode TRBSR status codes Leo Yan
2026-10-16 16:55 ` [PATCH v2 13/23] coresight: trbe: Simplify wrap status handling Leo Yan
2026-10-16 16:55 ` [PATCH v2 14/23] coresight: trbe: Treat access not allowed stops as fatal Leo Yan
2026-10-16 16:55 ` [PATCH v2 15/23] coresight: trbe: Report truncated trace on buffer update errors Leo Yan
2026-10-16 16:55 ` [PATCH v2 16/23] coresight: trbe: Always classify TRBSR when updating buffer Leo Yan
2026-10-16 16:55 ` [PATCH v2 17/23] coresight: trbe: Calculate trace size across buffer wrap Leo Yan
2026-10-16 16:55 ` [PATCH v2 18/23] coresight: trbe: Keep the perf handle in per-CPU data Leo Yan
2026-10-16 16:55 ` [PATCH v2 19/23] coresight: trbe: Reload the AUX buffer on overflow restart Leo Yan
2026-10-16 16:55 ` [PATCH v2 20/23] coresight: trbe: Add fault action argument to trbe_handle_overflow() Leo Yan
2026-10-16 16:55 ` [PATCH v2 21/23] coresight: trbe: Read TRBSR after prohibiting and flushing trace Leo Yan
2026-10-16 16:55 ` Leo Yan [this message]
2026-10-16 16:55 ` [PATCH v2 23/23] coresight: trbe: Report trace gaps with PARTIAL instead of COLLISION 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_enable_disable_irq_handle_refactor-v2-22-3f57cf3199b1@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

all inboxes | Powered by JetHome®