TRBSR_EL1 records the status of the buffer that just stopped. Clearing it in trbe_enable_hw() postpones cleanup until another run starts. If AUX output cannot restart, for example when AUX space is exhausted, that clear never executes. Clear the status in arm_trbe_disable() after disabling TRBE instead.
trbe_handle_overflow() can start the next run without calling arm_trbe_disable(). Clear the stopped buffer's syndrome and status bits while TRBE is disabled, before attempting the AUX restart. This also leaves the status clean when the restart fails.
Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-trbe.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 26e7554d6bdd31f8a55a8bc3a7b6d4c49b984b9b..dd9c9330bb0c739795f300dafc6ce34e72fbf280 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -655,7 +655,6 @@ static void trbe_enable_hw(struct trbe_buf *buf) WARN_ON(buf->trbe_hw_base < buf->trbe_base); WARN_ON(buf->trbe_write < buf->trbe_hw_base); WARN_ON(buf->trbe_write >= buf->trbe_limit); - clr_trbe_status(); set_trbe_base_pointer(buf->trbe_hw_base); set_trbe_write_pointer(buf->trbe_write);
@@ -1069,6 +1068,8 @@ static int arm_trbe_disable(struct coresight_device *csdev) return -EINVAL;
trbe_drain_and_disable_local(cpudata); + clr_trbe_status(); + buf->cpudata = NULL; cpudata->buf = NULL; cpudata->mode = CS_MODE_DISABLED; @@ -1095,6 +1096,13 @@ static int trbe_handle_overflow(struct perf_output_handle *handle) unsigned long size; struct etm_event_data *event_data;
+ /* + * Clear the status. No context synchronization is required here, + * since context synchronization will be performed before TRBE is + * re-enabled (see trbe_enable_hw()). + */ + clr_trbe_status(); + size = trbe_get_trace_size(handle, buf, true); if (buf->snapshot) handle->head += size;