Store the active path in the source device structure for system tracers (e.g. STM). Ensure the path pointer is cleared when the source is disabled.
Tested-by: James Clark james.clark@linaro.org Reviewed-by: Yeoreum Yun yeoreum.yun@arm.com Reviewed-by: James Clark james.clark@linaro.org Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 28 ++++++++++++++++++++++++++-- include/linux/coresight.h | 2 ++ 2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 4b55c54c5fbade99404ad662aa4111d4c3c2b85b..81bf4637f788f99844e839fd9dad8802ee78eb60 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -430,19 +430,43 @@ int coresight_enable_source(struct coresight_device *csdev, struct perf_event *event, enum cs_mode mode, struct coresight_path *path) { + int ret; + if (!coresight_is_device_source(csdev)) return -EINVAL;
- return source_ops(csdev)->enable(csdev, event, mode, path); + ret = source_ops(csdev)->enable(csdev, event, mode, path); + if (ret) + return ret; + + /* + * The per-CPU source has updated its path pointer in the enable() + * callback, ensuring synchronization on the target CPU. Set the + * path pointer here for non per-CPU sources. + */ + if (!coresight_is_percpu_source(csdev)) + csdev->path = path; + + return 0; }
void coresight_disable_source(struct coresight_device *csdev, void *data) { + struct coresight_path *path; + if (!coresight_is_device_source(csdev)) return;
+ /* + * The per-CPU source's disable callback may clear csdev->path, so + * save the path pointer used by disabling helper. + */ + path = csdev->path; source_ops(csdev)->disable(csdev, data); - coresight_disable_helpers(csdev, NULL); + coresight_disable_helpers(csdev, path); + + if (!coresight_is_percpu_source(csdev)) + csdev->path = NULL; } EXPORT_SYMBOL_GPL(coresight_disable_source);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h index f771615852b84200e37b844648a13bd18c91593d..11d61cdfac8d4d51e831a84635d8438383665d3e 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -268,6 +268,7 @@ struct coresight_trace_id_map { * spinlock. * @orphan: true if the component has connections that haven't been linked. * @cpu: The CPU this component is affined to (-1 for not CPU bound). + * @path: Activated path pointer (only used for source device). * @sysfs_sink_activated: 'true' when a sink has been selected for use via sysfs * by writing a 1 to the 'enable_sink' file. A sink can be * activated but not yet enabled. Enabling for a _sink_ happens @@ -295,6 +296,7 @@ struct coresight_device { int refcnt; bool orphan; int cpu; + struct coresight_path *path; /* sink specific fields */ bool sysfs_sink_activated; struct dev_ext_attribute *ea;