lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250701-arm_cs_pm_fix_v3-v2-24-23ebb864fcc1@arm.com>
Date: Tue, 01 Jul 2025 15:53:49 +0100
From: Leo Yan <leo.yan@....com>
To: Suzuki K Poulose <suzuki.poulose@....com>, 
 Mike Leach <mike.leach@...aro.org>, James Clark <james.clark@...aro.org>, 
 Levi Yun <yeoreum.yun@....com>, 
 Greg Kroah-Hartman <gregkh@...uxfoundation.org>, 
 Alexander Shishkin <alexander.shishkin@...ux.intel.com>, 
 Yabin Cui <yabinc@...gle.com>, Keita Morisaki <keyz@...gle.com>, 
 Yuanfang Zhang <quic_yuanfang@...cinc.com>
Cc: coresight@...ts.linaro.org, linux-arm-kernel@...ts.infradead.org, 
 linux-kernel@...r.kernel.org, Leo Yan <leo.yan@....com>
Subject: [PATCH v2 24/28] coresight: Add PM callbacks for percpu sink

Unlike a system level's sink, the per-CPU sink may lose power during CPU
idle states. Currently, this refers specifically to TRBE as the sink.
This commit registers save and restore callbacks for the per-CPU sink
via the PM notifier.

There are no changes to the coresight_enable_helpers() function; the
code movement is solely for compilation purposes.

Signed-off-by: Leo Yan <leo.yan@....com>
---
 drivers/hwtracing/coresight/coresight-core.c | 101 +++++++++++++++++++++------
 include/linux/coresight.h                    |   4 ++
 2 files changed, 82 insertions(+), 23 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 7693a0eade1a8de6d0960d66f6de682b5d5aff17..9978737d21177ab7cfcd449cf67a0b0736fcca5a 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -391,6 +391,25 @@ static void coresight_disable_helper(struct coresight_device *csdev, void *data)
 	helper_ops(csdev)->disable(csdev, data);
 }
 
+static int coresight_enable_helpers(struct coresight_device *csdev,
+				    enum cs_mode mode, void *data)
+{
+	int i, ret = 0;
+	struct coresight_device *helper;
+
+	for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
+		helper = csdev->pdata->out_conns[i]->dest_dev;
+		if (!helper || !coresight_is_helper(helper))
+			continue;
+
+		ret = coresight_enable_helper(helper, mode, data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static void coresight_disable_helpers(struct coresight_device *csdev, void *data)
 {
 	int i;
@@ -478,6 +497,43 @@ static void coresight_restore_source(struct coresight_device *csdev)
 		source_ops(csdev)->restore(csdev);
 }
 
+static int coresight_save_percpu_sink(struct coresight_device *csdev)
+{
+	int ret;
+
+	if (csdev && sink_ops(csdev)->save) {
+		ret = sink_ops(csdev)->save(csdev);
+		if (ret)
+			return ret;
+
+		coresight_disable_helpers(csdev, NULL);
+	}
+
+	/* Return success if callback is not supported */
+	return 0;
+}
+
+static int coresight_restore_percpu_sink(struct coresight_device *csdev,
+					 struct coresight_path *path,
+					 enum cs_mode mode)
+{
+	int ret = 0;
+
+	if (csdev && sink_ops(csdev)->restore) {
+		ret = coresight_enable_helpers(csdev, mode, path);
+		if (ret)
+			return ret;
+
+		ret = sink_ops(csdev)->restore(csdev);
+		if (ret) {
+			coresight_disable_helpers(csdev, path);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
 /*
  * coresight_disable_path_from : Disable components in the given path beyond
  * @nd in the list. If @nd is NULL, all the components, except the SOURCE are
@@ -551,25 +607,6 @@ void coresight_disable_path(struct coresight_path *path)
 }
 EXPORT_SYMBOL_GPL(coresight_disable_path);
 
-static int coresight_enable_helpers(struct coresight_device *csdev,
-				    enum cs_mode mode, void *data)
-{
-	int i, ret = 0;
-	struct coresight_device *helper;
-
-	for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
-		helper = csdev->pdata->out_conns[i]->dest_dev;
-		if (!helper || !coresight_is_helper(helper))
-			continue;
-
-		ret = coresight_enable_helper(helper, mode, data);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
 static int _coresight_enable_path(struct coresight_path *path,
 				  enum cs_mode mode, void *sink_data,
 				  bool in_idle)
@@ -1667,9 +1704,12 @@ EXPORT_SYMBOL_GPL(coresight_alloc_device_name);
 static int coresight_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 				   void *v)
 {
+	int ret;
 	unsigned int cpu = smp_processor_id();
 	struct coresight_device *source = per_cpu(csdev_source, cpu);
 	struct coresight_path *path;
+	struct coresight_device *sink;
+	enum cs_mode mode;
 
 	if (!coresight_need_save_restore_source(source))
 		return NOTIFY_OK;
@@ -1682,18 +1722,33 @@ static int coresight_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
 	if (WARN_ON(!path))
 		return NOTIFY_BAD;
 
+	sink = coresight_get_sink(path);
+	mode = coresight_get_mode(source);
+
 	switch (cmd) {
 	case CPU_PM_ENTER:
 		if (coresight_save_source(source))
 			return NOTIFY_BAD;
 
-		coresight_disable_path_from(path, NULL, true);
+		ret = 0;
+		if (coresight_is_percpu_sink(sink))
+			ret = coresight_save_percpu_sink(sink);
+		else
+			coresight_disable_path_from(path, NULL, true);
+
+		if (ret) {
+			coresight_restore_source(source);
+			return NOTIFY_BAD;
+		}
 		break;
 	case CPU_PM_EXIT:
 	case CPU_PM_ENTER_FAILED:
-		if (_coresight_enable_path(path,
-					   coresight_get_mode(source),
-					   NULL, true))
+		if (coresight_is_percpu_sink(sink))
+			ret = coresight_restore_percpu_sink(sink, path, mode);
+		else
+			ret = _coresight_enable_path(path, mode, NULL, true);
+
+		if (ret)
 			return NOTIFY_BAD;
 
 		coresight_restore_source(source);
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index f52e834640b72534ea83ab223aae7544b195bbaa..e551a36c40cc2311cd72948b799db5425b93fe68 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -363,6 +363,8 @@ enum cs_mode {
  * @alloc_buffer:	initialises perf's ring buffer for trace collection.
  * @free_buffer:	release memory allocated in @get_config.
  * @update_buffer:	update buffer pointers after a trace session.
+ * @save:		save context for a sink.
+ * @restore:		restore context for a sink.
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev, enum cs_mode mode,
@@ -375,6 +377,8 @@ struct coresight_ops_sink {
 	unsigned long (*update_buffer)(struct coresight_device *csdev,
 			      struct perf_output_handle *handle,
 			      void *sink_config);
+	int (*save)(struct coresight_device *csdev);
+	int (*restore)(struct coresight_device *csdev);
 };
 
 /**

-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ