mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 06:57:30 -04:00
coresight: Save active path for system tracers
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
This commit is contained in:
committed by
Suzuki K Poulose
parent
a18e877b04
commit
ac8eac9062
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user