[PATCH 3/4] coresight: tmc-etr: Fix race condition between sysfs and perf mode
Yicong Yang
yangyicong at huawei.com
Mon Dec 2 02:54:33 PST 2024
On 2024/12/2 17:46, Suzuki K Poulose wrote:
> 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)
>
ok, considering that maybe we can optimize it a bit more in the tmc_etr_get_sysfs_buffer().
Check whether the perf mode's already running before we actually allocate the buffer.
Then we can save the time of allocating/freeing the sysfs buffer if race with the perf mode.
Thanks.
More information about the linux-arm-kernel
mailing list