All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yeoreum Yun <yeoreum.yun@arm.com>
To: Leo Yan <leo.yan@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>,
	Mike Leach <mike.leach@linaro.org>,
	James Clark <james.clark@linaro.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Yabin Cui <yabinc@google.com>, Keita Morisaki <keyz@google.com>,
	Yuanfang Zhang <quic_yuanfang@quicinc.com>,
	coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 02/28] coresight: etm4x: Always set tracer's device mode on target CPU
Date: Wed, 2 Jul 2025 11:14:19 +0100	[thread overview]
Message-ID: <aGUGe82QxE+vCbx8@e129823.arm.com> (raw)
In-Reply-To: <20250701-arm_cs_pm_fix_v3-v2-2-23ebb864fcc1@arm.com>

LGTM.

Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>

> When enabling a tracer via SysFS interface, the device mode may be set
> by any CPU - not necessarily the target CPU. This can lead to race
> condition in SMP, and may result in incorrect mode values being read.
>
> Consider the following example, where CPU0 attempts to enable the tracer
> on CPU1 (the target CPU):
>
>  CPU0                                    CPU1
>  etm4_enable()
>   ` coresight_take_mode(SYSFS)
>   ` etm4_enable_sysfs()
>      ` smp_call_function_single() ---->  etm4_enable_hw_smp_call()
>      			                /
>                                        /  CPU idle:
>                                       /   etm4_cpu_save()
>                                      /     ` coresight_get_mode()
> 	       Failed to enable h/w /         ^^^
>   ` coresight_set_mode(DISABLED) <-'          Read the intermediate SYSFS mode
>
> In this case, CPU0 initiates the operation by taking the SYSFS mode to
> avoid conflicts with the Perf mode. It then sends an IPI to CPU1 to
> configure the tracer registers. If any error occurs during this process,
> CPU0 rolls back by setting the mode to DISABLED.
>
> However, if CPU1 enters an idle state during this time, it might read
> the intermediate SYSFS mode. As a result, the CPU PM flow could wrongly
> save and restore tracer context that is actually disabled.
>
> To resolve the issue, this commit moves the device mode setting logic on
> the target CPU. This ensures that the device mode is only modified by
> the target CPU, eliminating race condition between mode writes and reads
> across CPUs.
>
> An additional change introduces the etm4_disable_hw_smp_call() function
> for SMP calls, which disables the tracer and explicitly set the mode to
> DISABLED during SysFS operations.
>
> The flow is updated with this change:
>
>  CPU0                                    CPU1
>  etm4_enable()
>   ` etm4_enable_sysfs()
>      ` smp_call_function_single() ---->  etm4_enable_hw_smp_call()
>                                           ` coresight_take_mode(SYSFS)
> 	                                    Failed, set back to DISABLED
>                                           ` coresight_set_mode(DISABLED)
>
>                                           CPU idle:
>                                           etm4_cpu_save()
>                                            ` coresight_get_mode()
>                                               ^^^
>                                               Read out the DISABLED mode
>
> Fixes: c38a9ec2b2c1 ("coresight: etm4x: moving etm_drvdata::enable to atomic field")
> Signed-off-by: Leo Yan <leo.yan@arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 48 +++++++++++++++-------
>  1 file changed, 33 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 42e5d37403addc6ec81f2e3184522d67d1677c04..ee405c88ea5faa130819f96b00b8307f8764d58a 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -590,10 +590,23 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
>  static void etm4_enable_hw_smp_call(void *info)
>  {
>  	struct etm4_enable_arg *arg = info;
> +	struct coresight_device *csdev;
>
>  	if (WARN_ON(!arg))
>  		return;
> +
> +	csdev = arg->drvdata->csdev;
> +	if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) {
> +		/* Someone is already using the tracer */
> +		arg->rc = -EBUSY;
> +		return;
> +	}
> +
>  	arg->rc = etm4_enable_hw(arg->drvdata);
> +
> +	/* The tracer didn't start */
> +	if (arg->rc)
> +		coresight_set_mode(csdev, CS_MODE_DISABLED);
>  }
>
>  /*
> @@ -809,6 +822,9 @@ static int etm4_enable_perf(struct coresight_device *csdev,
>  	int ret = 0;
>  	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>
> +	if (!coresight_take_mode(csdev, CS_MODE_PERF))
> +		return -EBUSY;
> +
>  	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) {
>  		ret = -EINVAL;
>  		goto out;
> @@ -828,6 +844,9 @@ static int etm4_enable_perf(struct coresight_device *csdev,
>  	ret = etm4_enable_hw(drvdata);
>
>  out:
> +	/* The tracer didn't start */
> +	if (ret)
> +		coresight_set_mode(csdev, CS_MODE_DISABLED);
>  	return ret;
>  }
>
> @@ -880,11 +899,6 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
>  {
>  	int ret;
>
> -	if (!coresight_take_mode(csdev, mode)) {
> -		/* Someone is already using the tracer */
> -		return -EBUSY;
> -	}
> -
>  	switch (mode) {
>  	case CS_MODE_SYSFS:
>  		ret = etm4_enable_sysfs(csdev, path);
> @@ -896,10 +910,6 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
>  		ret = -EINVAL;
>  	}
>
> -	/* The tracer didn't start */
> -	if (ret)
> -		coresight_set_mode(csdev, CS_MODE_DISABLED);
> -
>  	return ret;
>  }
>
> @@ -951,10 +961,9 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata)
>  	isb();
>  }
>
> -static void etm4_disable_hw(void *info)
> +static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
>  {
>  	u32 control;
> -	struct etmv4_drvdata *drvdata = info;
>  	struct etmv4_config *config = &drvdata->config;
>  	struct coresight_device *csdev = drvdata->csdev;
>  	struct csdev_access *csa = &csdev->access;
> @@ -991,6 +1000,15 @@ static void etm4_disable_hw(void *info)
>  		"cpu: %d disable smp call done\n", drvdata->cpu);
>  }
>
> +static void etm4_disable_hw_smp_call(void *info)
> +{
> +	struct etmv4_drvdata *drvdata = info;
> +
> +	etm4_disable_hw(drvdata);
> +
> +	coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
> +}
> +
>  static int etm4_disable_perf(struct coresight_device *csdev,
>  			     struct perf_event *event)
>  {
> @@ -1020,6 +1038,8 @@ static int etm4_disable_perf(struct coresight_device *csdev,
>  	/* TRCVICTLR::SSSTATUS, bit[9] */
>  	filters->ssstatus = (control & BIT(9));
>
> +	coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
> +
>  	/*
>  	 * perf will release trace ids when _free_aux() is
>  	 * called at the end of the session.
> @@ -1045,7 +1065,8 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
>  	 * Executing etm4_disable_hw on the cpu whose ETM is being disabled
>  	 * ensures that register writes occur when cpu is powered.
>  	 */
> -	smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1);
> +	smp_call_function_single(drvdata->cpu, etm4_disable_hw_smp_call,
> +				 drvdata, 1);
>
>  	raw_spin_unlock(&drvdata->spinlock);
>
> @@ -1085,9 +1106,6 @@ static void etm4_disable(struct coresight_device *csdev,
>  		etm4_disable_perf(csdev, event);
>  		break;
>  	}
> -
> -	if (mode)
> -		coresight_set_mode(csdev, CS_MODE_DISABLED);
>  }
>
>  static int etm4_resume_perf(struct coresight_device *csdev)
>
> --
> 2.34.1
>

--
Sincerely,
Yeoreum Yun


  reply	other threads:[~2025-07-02 11:00 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-01 14:53 [PATCH v2 00/28] CoreSight: Address CPU Power Management Issues Leo Yan
2025-07-01 14:53 ` [PATCH v2 01/28] coresight: Change device mode to atomic type Leo Yan
2025-07-02  9:49   ` Yeoreum Yun
2025-07-02 10:38     ` Leo Yan
2025-07-02 16:35       ` Yeoreum Yun
2025-07-15  6:53   ` Anshuman Khandual
2025-08-04  8:22     ` Leo Yan
2025-07-01 14:53 ` [PATCH v2 02/28] coresight: etm4x: Always set tracer's device mode on target CPU Leo Yan
2025-07-02 10:14   ` Yeoreum Yun [this message]
2025-07-15  7:26   ` Anshuman Khandual
2025-08-04  9:08     ` Leo Yan
2025-08-21  9:45   ` James Clark
2025-08-21 12:51     ` Leo Yan
2025-07-01 14:53 ` [PATCH v2 03/28] coresight: etm3x: " Leo Yan
2025-07-02  3:04   ` kernel test robot
2025-07-02  4:08   ` kernel test robot
2025-07-02 10:18   ` Yeoreum Yun
2025-07-02 10:42     ` Leo Yan
2025-07-01 14:53 ` [PATCH v2 04/28] coresight: etm4x: Correct polling IDLE bit Leo Yan
2025-07-02 10:24   ` Yeoreum Yun
2025-07-01 14:53 ` [PATCH v2 05/28] coresight: etm4x: Ensure context synchronization is not ignored Leo Yan
2025-07-02 11:10   ` Yeoreum Yun
2025-07-02 14:35     ` Leo Yan
2025-07-01 14:53 ` [PATCH v2 06/28] coresight: etm4x: Add context synchronization before enabling trace Leo Yan
2025-07-02 11:05   ` Yeoreum Yun
2025-07-02 14:40     ` Leo Yan
2025-07-02 16:21       ` Yeoreum Yun
2025-07-01 14:53 ` [PATCH v2 07/28] coresight: etm4x: Properly control filter in CPU idle with FEAT_TRF Leo Yan
2025-07-01 14:53 ` [PATCH v2 08/28] coresight: etm4x: Remove the state_needs_restore flag Leo Yan
2025-07-02 11:19   ` Yeoreum Yun
2025-07-01 14:53 ` [PATCH v2 09/28] coresight: etm4x: Add flag to control single-shot restart Leo Yan
2025-07-01 14:53 ` [PATCH v2 10/28] coresight: etm4x: Reuse normal enable and disable logic in CPU idle Leo Yan
2025-07-01 14:53 ` [PATCH v2 11/28] coresight: Populate CPU ID into the coresight_device structure Leo Yan
2025-07-02  6:34   ` kernel test robot
2025-07-01 14:53 ` [PATCH v2 12/28] coresight: sysfs: Validate CPU online status for per-CPU sources Leo Yan
2025-07-02 12:55   ` Yeoreum Yun
2025-07-01 14:53 ` [PATCH v2 13/28] coresight: Set per CPU source pointer Leo Yan
2025-07-01 14:53 ` [PATCH v2 14/28] coresight: Register CPU PM notifier in core layer Leo Yan
2025-07-01 14:53 ` [PATCH v2 15/28] coresight: etm4x: Hook CPU PM callbacks Leo Yan
2025-07-01 14:53 ` [PATCH v2 16/28] coresight: Add callback to determine if context save/restore is needed Leo Yan
2025-07-01 14:53 ` [PATCH v2 17/28] coresight: etm4x: Remove redundant condition checks in save and restore Leo Yan
2025-07-01 14:53 ` [PATCH v2 18/28] coresight: cti: Fix race condition by using device mode Leo Yan
2025-07-01 14:53 ` [PATCH v2 19/28] coresight: cti: Introduce CS_MODE_DEBUG mode Leo Yan
2025-07-01 14:53 ` [PATCH v2 20/28] coresight: cti: Properly handle modes in CPU PM notifiers Leo Yan
2025-07-01 14:53 ` [PATCH v2 21/28] coresight: Add per-CPU path pointer Leo Yan
2025-07-01 14:53 ` [PATCH v2 22/28] coresight: Add 'in_idle' argument to path enable/disable functions Leo Yan
2025-07-01 14:53 ` [PATCH v2 23/28] coresight: Control path during CPU idle Leo Yan
2025-07-01 14:53 ` [PATCH v2 24/28] coresight: Add PM callbacks for percpu sink Leo Yan
2025-07-01 14:53 ` [PATCH v2 25/28] coresight: trbe: Save and restore state across CPU low power state Leo Yan
2025-09-04 13:15   ` James Clark
2025-07-01 14:53 ` [PATCH v2 26/28] coresight: Take hotplug lock in enable_source_store() for Sysfs mode Leo Yan
2025-07-01 14:53 ` [PATCH v2 27/28] coresight: Move CPU hotplug callbacks to core layer Leo Yan
2025-07-01 14:53 ` [PATCH v2 28/28] coresight: Manage activated path during CPU hotplug 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=aGUGe82QxE+vCbx8@e129823.arm.com \
    --to=yeoreum.yun@arm.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=coresight@lists.linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=james.clark@linaro.org \
    --cc=keyz@google.com \
    --cc=leo.yan@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mike.leach@linaro.org \
    --cc=quic_yuanfang@quicinc.com \
    --cc=suzuki.poulose@arm.com \
    --cc=yabinc@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.