]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
coresight: Save active path for system tracers
authorLeo Yan <leo.yan@arm.com>
Fri, 15 May 2026 20:08:26 +0000 (21:08 +0100)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 18 May 2026 09:18:46 +0000 (10:18 +0100)
This commit only set the path pointer for system tracers (e.g. STM) in
coresight_{enable|disable}_source().

Later changes will set the path pointer locally for per-CPU sources.
This is because the mode and path pointer must be set together, so that
they are observed atomically by the CPU PM notifier.

Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Tested-by: James Clark <james.clark@linaro.org>
Tested-by: Jie Gan <jie.gan@oss.qualcomm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20260515-arm_coresight_path_power_management_improvement-v14-19-f88c4a3ecfe9@arm.com
drivers/hwtracing/coresight/coresight-core.c
include/linux/coresight.h

index f833b73ebc168b2b039e5f0900594d0bde5ff916..7f6febd20faa64bc99336b368d0193221706fc2d 100644 (file)
@@ -487,10 +487,28 @@ 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;
+
+       /*
+        * Update the path pointer until after the source is enabled to avoid
+        * races where multiple paths attempt to enable the same source.
+        *
+        * Do not set the path pointer here for per-CPU sources; set it locally
+        * on the CPU instead. Otherwise, there is a window where the path is
+        * enabled but the pointer is not yet set, causing CPU PM notifiers to
+        * miss PM operations due to reading a NULL pointer.
+        */
+       if (!coresight_is_percpu_source(csdev))
+               csdev->path = path;
+
+       return 0;
 }
 
 void coresight_disable_source(struct coresight_device *csdev, void *data)
@@ -498,6 +516,9 @@ void coresight_disable_source(struct coresight_device *csdev, void *data)
        if (!coresight_is_device_source(csdev))
                return;
 
+       if (!coresight_is_percpu_source(csdev))
+               csdev->path = NULL;
+
        source_ops(csdev)->disable(csdev, data);
 }
 EXPORT_SYMBOL_GPL(coresight_disable_source);
index 5f9d7ea9f5941ab01eb6a084ca558a9417c7727f..58d474b269806d32cad6ed87da96550b06f1f30f 100644 (file)
@@ -257,6 +257,7 @@ struct coresight_trace_id_map {
  *             by @coresight_ops.
  * @access:    Device i/o access abstraction for this device.
  * @dev:       The device entity associated to this component.
+ * @path:      Activated path pointer (only used for source device).
  * @mode:      The device mode, i.e sysFS, Perf or disabled. This is actually
  *             an 'enum cs_mode' but stored in an atomic type. Access is always
  *             through atomic APIs, ensuring SMP-safe synchronisation between
@@ -291,6 +292,7 @@ struct coresight_device {
        const struct coresight_ops *ops;
        struct csdev_access access;
        struct device dev;
+       struct coresight_path *path;
        atomic_t mode;
        int refcnt;
        int cpu;