[PATCH v2 16/23] coresight: trbe: Always classify TRBSR when updating buffer

From: Leo Yan

Date: Fri Oct 16 2026 - 14:32:13 EST


arm_trbe_update_buffer() must account trace when perf stops a session,
even if no maintenance interrupt has been handled. Prepare it for
trigger and wrap modes by making the trace-size decision from the
drained TRBSR status rather than gating classification on IRQ.
Acknowledge IRQ only when it is set.

In FILL mode, reaching LIMIT sets WRAP and IRQ and returns TRBPTR to
BASE. Interrupt delivery can be delayed, so update_buffer() may run
before the IRQ handler. The existing IRQ-gated path uses WRAP to size
through LIMIT in that case; preserve this while also classifying
updates without a pending IRQ.

With classification on the no-IRQ path, a normal software stop can
have TRBSR.S clear and an ignored detected trigger can set TRBSR.TRG.
Neither should warn or discard valid trace. Mark fatal status as
truncated and return zero. Use LIMIT for a filled WRAP and TRBPTR
otherwise.

Signed-off-by: Leo Yan <leo.yan@xxxxxxx>
---
drivers/hwtracing/coresight/coresight-trbe.c | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index ac49098aa08412a23a20d32f84c2e1977ee4a223..661f4a78e67c30652de8c834e4773819fa67b5ac 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -662,8 +662,6 @@ static enum trbe_fault_action trbe_get_fault_act(struct perf_output_handle *hand
int ec = get_trbe_ec(trbsr);
int bsc = get_trbe_bsc(trbsr);

- WARN_ON(is_trbe_running(trbsr));
-
if (is_trbe_abort(trbsr)) {
err_str = "External abort";
goto out_fatal;
@@ -844,7 +842,6 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
enum trbe_fault_action act;
unsigned long size, status;
unsigned long flags;
- bool wrap = false;

WARN_ON(buf->cpudata != cpudata);
WARN_ON(cpudata->cpu != smp_processor_id());
@@ -896,23 +893,20 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
*/
clr_trbe_irq();
isb();
+ }

- act = trbe_get_fault_act(handle, status);
- /*
- * If this was not due to a WRAP event, we have some
- * errors and as such buffer is empty.
- */
- if (act != TRBE_FAULT_ACT_WRAP) {
- perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
- size = 0;
- goto done;
- }
+ act = trbe_get_fault_act(handle, status);

+ /* If an error occurred, the buffer may be empty */
+ if (act == TRBE_FAULT_ACT_FATAL) {
+ perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
+ size = 0;
+ goto done;
+ } else if (act == TRBE_FAULT_ACT_WRAP) {
trbe_report_wrap_event(handle);
- wrap = true;
}

- size = trbe_get_trace_size(handle, buf, wrap);
+ size = trbe_get_trace_size(handle, buf, act == TRBE_FAULT_ACT_WRAP);

done:
local_irq_restore(flags);

--
2.34.1