On 19/09/2025 02:20, Jie Gan wrote:
>
>
> On 9/19/2025 6:18 AM, Carl Worth wrote:
>> Jie Gan <jie.gan(a)oss.qualcomm.com> writes:
>>> I dont think we can change back to sink_data since we introduced
>>> coresight_path to wrap 'data' which is needed by the path.
>>>
>>> I suggest you to add the struct perf_output_handle to the
>>> coresight_path, then retrieving it with data->perf_handle in
>>> tmc_etr_get_buffer.
>> ...
>>> We can assign the perf_output_handle to the coresight_path after we
>>> constructed the coresight_path in perf mode.
>>
>> Thanks. That much makes sense to me, and I'll put together a patch along
>> those lines.
>>
>> But, further: with core coresight code assembling into the path all the
>> data that is necessary, is there any reason to be using void* in these
>> enable/disable functions?
>
> In my opinion, yes, we can change void * to coresight_path * for
> helper's enable/disable functions since we have everything in path so
> the cast is not necessary now.
>
>>
>> Could we also change these functions to accept a coresight_path* and
>> actually get some compiler help at finding mistakes like the one we're
>> fixing here?
>
Yes, please. I was going to suggest that. May be we could do that as
a separate patch after fixing the problem here first (so that it
can be back ported).
This was initially a perf_handle only used for the perf mode, and
it didn't make sens to have a "perf" argument to "enable" which
could be used for both sysfs and perf. Now that the path
is a generic data structure, it makes sense to move everything
to accept the path.
Suzuki
> That's the only benefit in my mind so far.
>
> Thanks,
> Jie
>
>>
>> -Carl
>
Jie Gan <jie.gan(a)oss.qualcomm.com> writes:
> I dont think we can change back to sink_data since we introduced
> coresight_path to wrap 'data' which is needed by the path.
>
> I suggest you to add the struct perf_output_handle to the
> coresight_path, then retrieving it with data->perf_handle in
> tmc_etr_get_buffer.
...
> We can assign the perf_output_handle to the coresight_path after we
> constructed the coresight_path in perf mode.
Thanks. That much makes sense to me, and I'll put together a patch along
those lines.
But, further: with core coresight code assembling into the path all the
data that is necessary, is there any reason to be using void* in these
enable/disable functions?
Could we also change these functions to accept a coresight_path* and
actually get some compiler help at finding mistakes like the one we're
fixing here?
-Carl
On 18/09/2025 10:15, Yicong Yang wrote:
> On 2025/8/18 16:05, Junhao He wrote:
>> 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 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)
>>
>> A race condition is introduced here, perf always prioritizes execution, and
>> warnings can lead to concerns about potential hidden bugs, such as getting
>> out of sync.
>>
>> To fix this, configure the tmc-etr mode before invoking enable_etr_perf()
>> or enable_etr_sysfs(), explicitly check if the tmc-etr sink is already
>> enabled in a different mode, and simplily the setup and checks for "mode".
>> To prevent race conditions between mode transitions.
>>
>> Fixes: 296b01fd106e ("coresight: Refactor out buffer allocation function for ETR")
>> Reported-by: Yicong Yang <yangyicong(a)hisilicon.com>
>> Closes: https://lore.kernel.org/linux-arm-kernel/20241202092419.11777-2-yangyicong@…
>> Signed-off-by: Junhao He <hejunhao3(a)huawei.com>
>
> Tested by running perf and sysfs mode simultaneously, no warning reproduced.
>
> Tested-by: Yicong Yang <yangyicong(a)hisilicon.com>
>
>> ---
>> .../hwtracing/coresight/coresight-tmc-etr.c | 80 ++++++++++---------
>> 1 file changed, 42 insertions(+), 38 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> index b07fcdb3fe1a..06c74717be19 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> @@ -1263,7 +1263,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
>> raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>> }
>>
>> - if (drvdata->reading || coresight_get_mode(csdev) == CS_MODE_PERF) {
>> + if (drvdata->reading) {
>> ret = -EBUSY;
>> goto out;
>> }
>> @@ -1300,20 +1300,18 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>> raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>>
>> /*
>> - * 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
>> - * touched, even if the buffer size has changed.
>> + * When two sysfs sessions race to acquire an idle sink, both may enter
>> + * this function. We need to recheck if the sink is already in use to
>> + * prevent duplicate hardware configuration.
>> */
>> - if (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
>> + if (csdev->refcnt) {
>> csdev->refcnt++;
>> goto out;
>> }
>>
>> ret = tmc_etr_enable_hw(drvdata, sysfs_buf);
>> - if (!ret) {
>> - coresight_set_mode(csdev, CS_MODE_SYSFS);
>> + if (!ret)
>> csdev->refcnt++;
>> - }
>>
>> out:
>> raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>> @@ -1729,39 +1727,24 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>> {
>> int rc = 0;
>> pid_t pid;
>> - unsigned long flags;
>> struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> struct perf_output_handle *handle = data;
>> struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
>>
>> - raw_spin_lock_irqsave(&drvdata->spinlock, flags);
>> - /* Don't use this sink if it is already claimed by sysFS */
>> - if (coresight_get_mode(csdev) == CS_MODE_SYSFS) {
>> - rc = -EBUSY;
>> - goto unlock_out;
>> - }
>> -
>> - if (WARN_ON(!etr_perf || !etr_perf->etr_buf)) {
>> - rc = -EINVAL;
>> - goto unlock_out;
>> - }
>> + if (WARN_ON(!etr_perf || !etr_perf->etr_buf))
>> + return -EINVAL;
>>
>> /* Get a handle on the pid of the session owner */
>> pid = etr_perf->pid;
>>
>> /* Do not proceed if this device is associated with another session */
>> - if (drvdata->pid != -1 && drvdata->pid != pid) {
>> - rc = -EBUSY;
>> - goto unlock_out;
>> - }
>> + if (drvdata->pid != -1 && drvdata->pid != pid)
>> + return -EBUSY;
>>
>> - /*
>> - * No HW configuration is needed if the sink is already in
>> - * use for this session.
>> - */
>> + /* The sink is already in use for this session */
>> if (drvdata->pid == pid) {
>> csdev->refcnt++;
>> - goto unlock_out;
>> + return rc;
>> }
>>
>> rc = tmc_etr_enable_hw(drvdata, etr_perf->etr_buf);
>> @@ -1773,22 +1756,43 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>> csdev->refcnt++;
>> }
>>
>> -unlock_out:
>> - raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
>> return rc;
>> }
>>
>> static int tmc_enable_etr_sink(struct coresight_device *csdev,
>> enum cs_mode mode, void *data)
>> {
>> - switch (mode) {
>> - case CS_MODE_SYSFS:
>> - return tmc_enable_etr_sink_sysfs(csdev);
>> - case CS_MODE_PERF:
>> - return tmc_enable_etr_sink_perf(csdev, data);
>> - default:
>> - return -EINVAL;
>> + struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> + int rc;
>> +
>> + scoped_guard(raw_spinlock_irqsave, &drvdata->spinlock) {
>> + if (coresight_get_mode(csdev) != CS_MODE_DISABLED &&
>> + coresight_get_mode(csdev) != mode)
>> + return -EBUSY;
>> +
>> + switch (mode) {
>> + case CS_MODE_SYSFS:
>> + if (csdev->refcnt) {
>> + /* The sink is already enabled */
>> + csdev->refcnt++;
>> + return 0;
>> + }
>> + coresight_set_mode(csdev, mode);
Why are we spilling bits here in the common code for sysfs ? More on
this, see below.
>> + break;
>> + case CS_MODE_PERF:
>> + return tmc_enable_etr_sink_perf(csdev, data);
>> + default:
>> + return -EINVAL;
>> + }
>> + }
>> +
>> + rc = tmc_enable_etr_sink_sysfs(csdev);
We now call the above function without the spinlock and the refcnt is
managed with and without the spinlock by the users. This is problematic,
with refcnt being a non-atomic type.
Please fix. I don't see why we can't set the mode in
tmc_enable_etr_sink_sysfs() with the locks held and
reset the mode if we failed enable it properly.
Suzuki
>> + if (rc) {
>> + scoped_guard(raw_spinlock_irqsave, &drvdata->spinlock)
>> + coresight_set_mode(csdev, CS_MODE_DISABLED);
>> }
>> +
>> + return rc;
>> }
>>
>> static int tmc_disable_etr_sink(struct coresight_device *csdev)
>>
Hi,
I will be making the OpenCSD ITM support in the development branch
(itm-decoder-dev) part of the main upstream branch.
If anyone has any feedback on this support please let me know.
Mike
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
If the AUX buffer size is specified as 2 GiB or larger, the expression
"(buf)->nr_pages << PAGE_SHIFT" may exceed 0x8000_0000. Since
(buf)->nr_pages is a signed integer, the shift can overflow and produce
a negative value. As a result, PERF_IDX2OFF() fails to work correctly.
Fix this by casting (buf)->nr_pages to unsigned long before the shift,
which allows PERF_IDX2OFF() to handle large buffers properly.
Signed-off-by: Leo Yan <leo.yan(a)arm.com>
---
Leo Yan (2):
coresight: trbe: Prevent overflow in PERF_IDX2OFF()
perf: arm_spe: Prevent overflow in PERF_IDX2OFF()
drivers/hwtracing/coresight/coresight-trbe.c | 3 ++-
drivers/perf/arm_spe_pmu.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
---
base-commit: 5aca7966d2a7255ba92fd5e63268dd767b223aa5
change-id: 20250917-fix_aux_trace_index-9745674f5061
Best regards,
--
Leo Yan <leo.yan(a)arm.com>
On Wed, Sep 17, 2025 at 09:35:55AM +0800, Jie Gan wrote:
[...]
> > diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> > index fa758cc21827..b1077d73c988 100644
> > --- a/drivers/hwtracing/coresight/coresight-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-core.c
> > @@ -510,7 +510,7 @@ int coresight_enable_path(struct coresight_path *path, enum cs_mode mode,
> > type = csdev->type;
> > /* Enable all helpers adjacent to the path first */
> > - ret = coresight_enable_helpers(csdev, mode, path);
> > + ret = coresight_enable_helpers(csdev, mode, sink_data);
>
> I dont think we can change back to sink_data since we introduced
> coresight_path to wrap 'data' which is needed by the path.
This change can fix catu issue but will cause regression for ctcu
driver.
> I suggest you to add the struct perf_output_handle to the coresight_path,
> then retrieving it with data->perf_handle in tmc_etr_get_buffer.
>
> before:
> struct perf_output_handle *handle = data;
>
> after:
> struct coresight_path *path = data;
> struct perf_output_handle *handle = path->perf_handle;
>
> We can assign the perf_output_handle to the coresight_path after we
> constructed the coresight_path in perf mode.
The suggestion looks good to me.
Thanks,
Leo
On Tue, Sep 16, 2025 at 12:51:11PM -0400, Sean Anderson wrote:
> On 9/16/25 12:48, Leo Yan wrote:
> > On Tue, Sep 16, 2025 at 12:14:40PM -0400, Sean Anderson wrote:
> >
> > [...]
> >
> >> > Could you check if the drafted patch below looks good to you? If so, I
> >>
> >> As stated above I disagree with a half-hearted removal. If you want to do that,
> >> then I will resend v2 done with an rcu list and you can make your own follow-up.
> >
> > It is fine to disagree, but please don't resend v2 :)
> >
> > We have plan to refactor locking in CoreSight driver, I will try my
> > best to avoid adding new lock unless with a strong reason.
>
> As said above it will be done with an rcu list, so no new lock.
>
> Or I can do this patch but stick the notifier block in csdev as suggested by Suzuki.
I am fine for adding the notifier block in csdev.
Suzuki, could you confirm if this is the right way to move forward?
Thanks,
Leo
This patch series adds support for the Qualcomm CoreSight Interconnect TNOC
(Trace Network On Chip) block, which acts as a CoreSight graph link forwarding
trace data from subsystems to the Aggregator TNOC. Unlike the Aggregator TNOC,
this block does not support aggregation or ATID assignment.
Signed-off-by: Yuanfang Zhang <yuanfang.zhang(a)oss.qualcomm.com>
---
Changes in v4:
- Fix unintended blank line removals in trace_noc_enable_hw.
- Link to v3: https://lore.kernel.org/r/20250828-itnoc-v3-0-f1b55dea7a27@oss.qualcomm.com
Changes in v3:
- Add detail for changes in V2.
- Remove '#address-cells' and '#size-cells' properties from in-ports field.
- Fix comment indentation for packet description.
- Link to v2: https://lore.kernel.org/r/20250819-itnoc-v2-0-2d0e6be44e2f@oss.qualcomm.com
Changes in v2:
- Removed the trailing '|' after the description in qcom,coresight-itnoc.yaml.
- Dropped the 'select' section from the YAML file.
- Updated node name to use a more generic naming convention.
- Removed the 'items' property from the compatible field.
- Deleted the description for the reg property.
- Dropped clock-names and adjusted the order of clock-names and clocks.
- Moved additionalProperties to follow the $ref of out-ports.
- Change "atid" type from u32 to int, set it as "-EOPNOTSUPP" for non-AMBA device.
- Link to v1: https://lore.kernel.org/r/20250815-itnoc-v1-0-62c8e4f7ad32@oss.qualcomm.com
---
Yuanfang Zhang (3):
dt-bindings: arm: qcom: Add Coresight Interconnect TNOC
coresight-tnoc: add platform driver to support Interconnect TNOC
coresight-tnoc: Add runtime PM support for Interconnect TNOC
.../bindings/arm/qcom,coresight-itnoc.yaml | 90 ++++++++++++++
drivers/hwtracing/coresight/coresight-tnoc.c | 136 +++++++++++++++++++--
2 files changed, 215 insertions(+), 11 deletions(-)
---
base-commit: 2b52cf338d39d684a1c6af298e8204902c026aca
change-id: 20250815-itnoc-460273d1b80c
Best regards,
--
Yuanfang Zhang <yuanfang.zhang(a)oss.qualcomm.com>