[PATCH v2 23/23] coresight: trbe: Report trace gaps with PARTIAL instead of COLLISION
From: Leo Yan
Date: Fri Oct 16 2026 - 13:24:47 EST
When a fill-mode wrap stops TRBE, the trace source can continue running
until software handles the stop. Trace generated during this interval
may be lost.
The overflow path now stops and restarts the trace source around buffer
reprogramming. This emits ASYNC packets so the decoder can synchronize
with the next trace segment. Use PERF_AUX_FLAG_PARTIAL to report the
possible gap instead of PERF_AUX_FLAG_COLLISION.
Set PARTIAL in both the overflow handler and the buffer update callback.
This also preserves the gap indication when event shutdown handles a
pending wrap, even if no further trace segment follows. Limit the flag
to stopped buffers.
Signed-off-by: Leo Yan <leo.yan@xxxxxxx>
---
drivers/hwtracing/coresight/coresight-trbe.c | 29 +++++++---------------------
1 file changed, 7 insertions(+), 22 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 6bc82d5b55539795059da37039d2929b4ea504e3..29a1882b1f3c2eb7166f71eeef37badece67039c 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -285,25 +285,6 @@ static void trbe_reset_local(struct trbe_cpudata *cpudata)
write_sysreg_s(0, SYS_TRBSR_EL1);
}
-static void trbe_report_wrap_event(struct perf_output_handle *handle)
-{
- /*
- * Mark the buffer to indicate that there was a WRAP event by
- * setting the COLLISION flag. This indicates to the user that
- * the TRBE trace collection was stopped without stopping the
- * ETE and thus there might be some amount of trace that was
- * lost between the time the WRAP was detected and the IRQ
- * was consumed by the CPU.
- *
- * Setting the TRUNCATED flag would move the event to STOPPED
- * state unnecessarily, even when there is space left in the
- * ring buffer. Using the COLLISION flag doesn't have this side
- * effect. We only set TRUNCATED flag when there is no space
- * left in the ring buffer.
- */
- perf_aux_output_flag(handle, PERF_AUX_FLAG_COLLISION);
-}
-
static void trbe_truncate_event(struct perf_output_handle *handle)
{
perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
@@ -917,10 +898,12 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
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);
}
+ /* Trace may have been lost before the source was stopped. */
+ if (act == TRBE_FAULT_ACT_WRAP && !is_trbe_running(status))
+ perf_aux_output_flag(handle, PERF_AUX_FLAG_PARTIAL);
+
size = trbe_get_trace_size(handle, buf, act == TRBE_FAULT_ACT_WRAP);
done:
@@ -1246,7 +1229,9 @@ static int trbe_handle_overflow(struct trbe_cpudata *cpudata,
if (buf->snapshot)
handle->head += size;
- trbe_report_wrap_event(handle);
+ if (is_buffer_stopped)
+ perf_aux_output_flag(handle, PERF_AUX_FLAG_PARTIAL);
+
perf_aux_output_end(handle, size);
event_data = perf_aux_output_begin(handle, event);
/*
--
2.34.1