Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Suzuki K Poulose <suzuki.poulose@arm.com>
To: Leo Yan <leo.yan@arm.com>, Mike Leach <mike.leach@arm.com>,
	James Clark <james.clark@linaro.org>,
	Yeoreum Yun <yeoreum.yun@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Will Deacon <will@kernel.org>, Yabin Cui <yabinc@google.com>,
	Keita Morisaki <keyz@google.com>,
	Jie Gan <jie.gan@oss.qualcomm.com>,
	Yuanfang Zhang <quic_yuanfang@quicinc.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Tamas Petz <tamas.petz@arm.com>,
	Thomas Gleixner <tglx@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>
Cc: coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v12 23/28] coresight: Control path during CPU idle
Date: Fri, 15 May 2026 16:45:51 +0100	[thread overview]
Message-ID: <d1793d84-3a69-41c4-9cd4-1d52a64d12ae@arm.com> (raw)
In-Reply-To: <20260511-arm_coresight_path_power_management_improvement-v12-23-1c9dcb1de8c9@arm.com>

On 11/05/2026 12:11, Leo Yan wrote:
> Extend the CPU PM flow to control the path: disable from source up to
> the node before the sink, then re-enable the same range on restore.
> To avoid latency, control it up to the node before the sink.
> 
> Track per-CPU PM restore failures using percpu_pm_failed.  Once a CPU
> hits a restore failure, set the percpu_pm_failed and return NOTIFY_BAD
> on subsequent notifications to avoid repeating half-completed
> transitions.
> 
> Setting percpu_pm_failed permanently blocks CPU PM on that CPU.  Such
> failures are typically seen during development; disabling PM operations
> simplifies the implementation, and a warning highlights the issue.
> 
> Reviewed-by: James Clark <james.clark@linaro.org>
> Tested-by: Jie Gan <jie.gan@oss.qualcomm.com>
> Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
> Tested-by: James Clark <james.clark@linaro.org>
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-core.c | 90 +++++++++++++++++++++++-----
>   1 file changed, 75 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index f07f6f28b9162911cdc673a454702f3ac4dc29ad..674fc375ff44e732405563af7be9dc8fae118e41 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -38,6 +38,7 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
>   
>   static DEFINE_RAW_SPINLOCK(coresight_dev_lock);
>   static DEFINE_PER_CPU(struct coresight_device *, csdev_source);
> +static DEFINE_PER_CPU(bool, percpu_pm_failed);

We have to reset this when the ETM4x module is taken off or the etmN
device is unregistered ?

Rest looks fine to me.

Suzuki


>   
>   /**
>    * struct coresight_node - elements of a path, from source to sink
> @@ -1840,7 +1841,7 @@ static void coresight_release_device_list(void)
>   	}
>   }
>   
> -static struct coresight_device *coresight_cpu_get_active_source(void)
> +static struct coresight_path *coresight_cpu_get_active_path(void)
>   {
>   	struct coresight_device *source;
>   	bool is_active = false;
> @@ -1856,22 +1857,32 @@ static struct coresight_device *coresight_cpu_get_active_source(void)
>   
>   	/*
>   	 * It is expected to run in atomic context, so it cannot be preempted
> -	 * to disable the source. Here returns the active source pointer
> -	 * without concern that its state may change. Since the build path has
> -	 * taken a reference on the component, the source can be safely used
> -	 * by the caller.
> +	 * to disable the path. Here returns the active path pointer without
> +	 * concern that its state may change. Since the build path has taken
> +	 * a reference on the component, the path can be safely used by the
> +	 * caller.
>   	 */
> -	return is_active ? source : NULL;
> +	return is_active ? source->path : NULL;
>   }
>   
> -static int coresight_pm_is_needed(struct coresight_device *csdev)
> +/* Return: 1 if PM is required, 0 if skip, or a negative error */
> +static int coresight_pm_is_needed(struct coresight_path *path)
>   {
> -	if (!csdev)
> +	struct coresight_device *source;
> +
> +	if (this_cpu_read(percpu_pm_failed))
> +		return -EIO;
> +
> +	if (!path)
> +		return 0;
> +
> +	source = coresight_get_source(path);
> +	if (!source)
>   		return 0;
>   
>   	/* pm_save_disable() and pm_restore_enable() must be paired */
> -	if (coresight_ops(csdev)->pm_save_disable &&
> -	    coresight_ops(csdev)->pm_restore_enable)
> +	if (coresight_ops(source)->pm_save_disable &&
> +	    coresight_ops(source)->pm_restore_enable)
>   		return 1;
>   
>   	return 0;
> @@ -1887,22 +1898,71 @@ static void coresight_pm_device_restore(struct coresight_device *csdev)
>   	coresight_ops(csdev)->pm_restore_enable(csdev);
>   }
>   
> +static int coresight_pm_save(struct coresight_path *path)
> +{
> +	struct coresight_device *source = coresight_get_source(path);
> +	struct coresight_node *from, *to;
> +	int ret;
> +
> +	ret = coresight_pm_device_save(source);
> +	if (ret)
> +		return ret;
> +
> +	from = coresight_path_first_node(path);
> +	/* Disable up to the node before sink */
> +	to = list_prev_entry(coresight_path_last_node(path), link);
> +	coresight_disable_path_from_to(path, from, to);
> +
> +	return 0;
> +}
> +
> +static void coresight_pm_restore(struct coresight_path *path)
> +{
> +	struct coresight_device *source = coresight_get_source(path);
> +	struct coresight_node *from, *to;
> +	int ret;
> +
> +	from = coresight_path_first_node(path);
> +	/* Enable up to the node before sink */
> +	to = list_prev_entry(coresight_path_last_node(path), link);
> +	ret = coresight_enable_path_from_to(path, coresight_get_mode(source),
> +					    from, to);
> +	if (ret)
> +		goto path_failed;
> +
> +	coresight_pm_device_restore(source);
> +	return;
> +
> +path_failed:
> +	pr_err("Failed in coresight PM restore on CPU%d: %d\n",
> +	       smp_processor_id(), ret);
> +
> +	/*
> +	 * Once PM fails on a CPU, set percpu_pm_failed and leave it set until
> +	 * reboot. This prevents repeated partial transitions during idle
> +	 * entry and exit.
> +	 */
> +	this_cpu_write(percpu_pm_failed, true);
> +}
> +
>   static int coresight_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
>   				   void *v)
>   {
> -	struct coresight_device *csdev = coresight_cpu_get_active_source();
> +	struct coresight_path *path = coresight_cpu_get_active_path();
> +	int ret;
>   
> -	if (!coresight_pm_is_needed(csdev))
> -		return NOTIFY_DONE;
> +	ret = coresight_pm_is_needed(path);
> +	if (ret <= 0)
> +		return ret ? NOTIFY_BAD : NOTIFY_DONE;
>   
>   	switch (cmd) {
>   	case CPU_PM_ENTER:
> -		if (coresight_pm_device_save(csdev))
> +		if (coresight_pm_save(path))
>   			return NOTIFY_BAD;
>   		break;
>   	case CPU_PM_EXIT:
>   	case CPU_PM_ENTER_FAILED:
> -		coresight_pm_device_restore(csdev);
> +		coresight_pm_restore(path);
>   		break;
>   	default:
>   		return NOTIFY_DONE;
> 



  reply	other threads:[~2026-05-15 15:46 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-11 11:10 [PATCH v12 00/28] CoreSight: Refactor power management for CoreSight path Leo Yan
2026-05-11 11:10 ` [PATCH v12 01/28] coresight: Fix source not disabled on idr_alloc_u32 failure Leo Yan
2026-05-11 11:10 ` [PATCH v12 02/28] coresight: Handle helper enable failure properly Leo Yan
2026-05-11 11:10 ` [PATCH v12 03/28] coresight: Extract device init into coresight_init_device() Leo Yan
2026-05-11 11:10 ` [PATCH v12 04/28] coresight: Populate CPU ID into coresight_device Leo Yan
2026-05-11 11:10 ` [PATCH v12 05/28] coresight: Remove .cpu_id() callback from source ops Leo Yan
2026-05-11 11:10 ` [PATCH v12 06/28] coresight: Take hotplug lock in enable_source_store() for Sysfs mode Leo Yan
2026-05-11 11:10 ` [PATCH v12 07/28] coresight: perf: Retrieve path and source from event data Leo Yan
2026-05-11 11:10 ` [PATCH v12 08/28] coresight: Take a reference on csdev Leo Yan
2026-05-11 11:10 ` [PATCH v12 09/28] coresight: Move per-CPU source pointer to core layer Leo Yan
2026-05-11 11:10 ` [PATCH v12 10/28] coresight: Take per-CPU source reference during AUX setup Leo Yan
2026-05-11 11:10 ` [PATCH v12 11/28] coresight: Register CPU PM notifier in core layer Leo Yan
2026-05-11 11:10 ` [PATCH v12 12/28] coresight: etm4x: Hook CPU PM callbacks Leo Yan
2026-05-11 11:10 ` [PATCH v12 13/28] coresight: etm4x: Remove redundant checks in PM save and restore Leo Yan
2026-05-11 11:10 ` [PATCH v12 14/28] coresight: syscfg: Use IRQ-safe spinlock to protect active variables Leo Yan
2026-05-11 11:10 ` [PATCH v12 15/28] coresight: Disable source helpers in coresight_disable_path() Leo Yan
2026-05-11 11:11 ` [PATCH v12 16/28] coresight: Control path with range Leo Yan
2026-05-11 11:11 ` [PATCH v12 17/28] coresight: Use helpers to fetch first and last nodes Leo Yan
2026-05-11 11:11 ` [PATCH v12 18/28] coresight: Introduce coresight_enable_source() helper Leo Yan
2026-05-11 11:11 ` [PATCH v12 19/28] coresight: Save active path for system tracers Leo Yan
2026-05-15 10:54   ` Suzuki K Poulose
2026-05-15 11:18     ` Leo Yan
2026-05-11 11:11 ` [PATCH v12 20/28] coresight: etm4x: Set active path on target CPU Leo Yan
2026-05-11 11:11 ` [PATCH v12 21/28] coresight: etm3x: " Leo Yan
2026-05-11 11:11 ` [PATCH v12 22/28] coresight: sysfs: Use source's path pointer for path control Leo Yan
2026-05-11 11:11 ` [PATCH v12 23/28] coresight: Control path during CPU idle Leo Yan
2026-05-15 15:45   ` Suzuki K Poulose [this message]
2026-05-11 11:11 ` [PATCH v12 24/28] coresight: Add PM callbacks for sink device Leo Yan
2026-05-11 11:11 ` [PATCH v12 25/28] coresight: trbe: Save and restore state across CPU low power state Leo Yan
2026-05-11 11:11 ` [PATCH v12 26/28] coresight: sysfs: Increment refcount only for software source Leo Yan
2026-05-11 11:11 ` [PATCH v12 27/28] coresight: Move CPU hotplug callbacks to core layer Leo Yan
2026-05-11 11:11 ` [PATCH v12 28/28] coresight: sysfs: Validate CPU online status for per-CPU sources Leo Yan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d1793d84-3a69-41c4-9cd4-1d52a64d12ae@arm.com \
    --to=suzuki.poulose@arm.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=coresight@lists.linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=james.clark@linaro.org \
    --cc=jie.gan@oss.qualcomm.com \
    --cc=keyz@google.com \
    --cc=leo.yan@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=mike.leach@arm.com \
    --cc=peterz@infradead.org \
    --cc=quic_yuanfang@quicinc.com \
    --cc=tamas.petz@arm.com \
    --cc=tglx@kernel.org \
    --cc=will@kernel.org \
    --cc=yabinc@google.com \
    --cc=yeoreum.yun@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox