[PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs and perf mode

Suzuki K Poulose suzuki.poulose at arm.com
Mon Dec 2 01:46:55 PST 2024


Hi Yicong

On 02/12/2024 09:24, Yicong Yang wrote:
> From: Yicong Yang <yangyicong at hisilicon.com>
> 
> When trying to run perf and sysfs mode simultaneously, the WARN_ON()
> in tmc_etr_enable_hw() is triggered sometimes:
> 
>   WARNING: CPU: 42 PID: 3911571 at drivers/hwtracing/coresight/coresight-tmc-etr.c:1060 tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc]
>   [..snip..]
>   Call trace:
>    tmc_etr_enable_hw+0xc0/0xd8 [coresight_tmc] (P)
>    tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc] (L)
>    tmc_enable_etr_sink+0x11c/0x250 [coresight_tmc]
>    coresight_enable_path+0x1c8/0x218 [coresight]
>    coresight_enable_sysfs+0xa4/0x228 [coresight]
>    enable_source_store+0x58/0xa8 [coresight]
>    dev_attr_store+0x20/0x40
>    sysfs_kf_write+0x4c/0x68
>    kernfs_fop_write_iter+0x120/0x1b8
>    vfs_write+0x2c8/0x388
>    ksys_write+0x74/0x108
>    __arm64_sys_write+0x24/0x38
>    el0_svc_common.constprop.0+0x64/0x148
>    do_el0_svc+0x24/0x38
>    el0_svc+0x3c/0x130
>    el0t_64_sync_handler+0xc8/0xd0
>    el0t_64_sync+0x1ac/0x1b0
>   ---[ end trace 0000000000000000 ]---
> 
> Since the enablement of sysfs mode is separeted into two critical regions,
> one for sysfs buffer allocation and another for hardware enablement, it's
> possible to race with the perf mode. Fix this by double check whether
> the perf mode's been used before enabling the hardware in sysfs mode.

Thanks for the fix. Some minor comments below.

It needs a Fixes tag.

> 
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>   .../hwtracing/coresight/coresight-tmc-etr.c   | 30 +++++++++++++++++++
>   1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index ad83714ca4dc..d382d95da5ff 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1230,6 +1230,36 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>   
>   	spin_lock_irqsave(&drvdata->spinlock, flags);
>   
> +	/*
> +	 * Since the sysfs buffer allocation and the hardware enablement is not
> +	 * in the same critical region, it's possible to race with the perf
> +	 * mode:
> +	 *   [sysfs mode]                   [perf mode]
> +	 *   tmc_etr_get_sysfs_buffer()
> +	 *     spin_lock(&drvdata->spinlock)
> +	 *     [sysfs buffer allocation]
> +	 *     spin_unlock(&drvdata->spinlock)
> +	 *                                  spin_lock(&drvdata->spinlock)
> +	 *                                  tmc_etr_enable_hw()
> +	 *                                    drvdata->etr_buf = etr_perf->etr_buf
> +	 *                                  spin_unlock(&drvdata->spinlock)
> +	 *   spin_lock(&drvdata->spinlock)
> +	 *   tmc_etr_enable_hw()
> +	 *     WARN_ON(drvdata->etr_buf) // WARN sicne etr_buf initialized at
> +	 *                                  the perf side
> +	 *   spin_unlock(&drvdata->spinlock)
> +	 *
> +	 * So check here before continue.
> +	 */
> +	if (coresight_get_mode(csdev) == CS_MODE_PERF) {
> +		drvdata->sysfs_buf = NULL;
> +		spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +
> +		/* Free allocated memory out side of the spinlock */
> +		tmc_etr_free_sysfs_buf(sysfs_buf);
> +		return -EBUSY;
> +	}

With this in place, I think we should remove the check for CS_MODE_PERF 
in get_etr_sysfs_buf() to avoid confusion (which I believe opened up 
this race)

Suzuki



> +
>   	/*
>   	 * In sysFS mode we can have multiple writers per sink.  Since this
>   	 * sink is already enabled no memory is needed and the HW need not be




More information about the linux-arm-kernel mailing list