etm-perf owns the perf output handle embedded in its per-CPU etm_ctxt and passes it to TRBE through arm_trbe_enable(). TRBE binds that handle after successful sink enable and unbinds it in arm_trbe_disable(). The handle object remains valid throughout this interval, even if the current AUX transaction ends or a new transaction begins.
The inner enable helper currently publishes the handle, while truncation and failed rollover clear it. Sink disable leaves the handle installed after dropping the buffer association. These assignments track the AUX transaction rather than the enabled sink session.
Publish the handle only in arm_trbe_enable() after successful setup and clear it in arm_trbe_disable() before dropping the buffer association. Remove the assignments from the inner enable, overflow and truncation paths so the handle association follows the enabled sink session.
A valid handle object may have no active AUX transaction, so the IRQ handler continues to check perf_get_aux() before accessing the transaction's configuration.
Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-trbe.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 4a041bbc6e970d72a7d735e15f7221037cb091d6..1f51c33de83638479436683fd96e31d69c3b860f 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -303,11 +303,8 @@ static void trbe_report_wrap_event(struct perf_output_handle *handle)
static void trbe_truncate_event(struct perf_output_handle *handle) { - struct trbe_buf *buf = etm_perf_sink_config(handle); - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); perf_aux_output_end(handle, 0); - *this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL; }
/* @@ -1012,7 +1009,6 @@ static int __arm_trbe_enable(struct trbe_buf *buf, if (ret) goto err;
- *this_cpu_ptr(buf->cpudata->drvdata->handle) = handle; trbe_enable_hw(buf); return 0; err: @@ -1042,6 +1038,7 @@ static int arm_trbe_enable(struct coresight_device *csdev, enum cs_mode mode, return ret; }
+ *this_cpu_ptr(drvdata->handle) = handle; cpudata->buf = buf; cpudata->mode = mode; return 0; @@ -1062,6 +1059,7 @@ static int arm_trbe_disable(struct coresight_device *csdev) trbe_drain_and_disable_local(cpudata); clr_trbe_status();
+ *this_cpu_ptr(drvdata->handle) = NULL; buf->cpudata = NULL; cpudata->buf = NULL; cpudata->mode = CS_MODE_DISABLED; @@ -1102,16 +1100,12 @@ static int trbe_handle_overflow(struct perf_output_handle *handle) trbe_report_wrap_event(handle); perf_aux_output_end(handle, size); event_data = perf_aux_output_begin(handle, event); - if (!event_data) { - /* - * We are unable to restart the trace collection, - * thus leave the TRBE disabled. The etm-perf driver - * is able to detect this with a disconnected handle - * (handle->event = NULL). - */ - *this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL; + /* + * If trace collection cannot be restarted, leave TRBE disabled. + * The etm-perf driver detects this through handle->event == NULL. + */ + if (!event_data) return -EINVAL; - }
return __arm_trbe_enable(buf, handle); }