[PATCH v1 01/11] coresight: etm4x: Control the trace unit in CPU suspend
Suzuki K Poulose
suzuki.poulose at arm.com
Wed Jun 4 02:48:49 PDT 2025
On 03/06/2025 14:40, James Clark wrote:
>
>
> On 16/05/2025 5:07 pm, Leo Yan wrote:
>> If a trace unit has been enabled, a CPU suspend operation misses to
>> disable the trace unit. After the CPU resumes, it also does not follow
>> the general flow for re-enabling the trace unit. As a result, this may
>> lead to a wrong state machine for the ETM.
>>
>> This commit stops the trace unit during the CPU suspend flow and
>> re-enables the trace unit in the resume flow.
>>
>> Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU
>> low power states")
>> Signed-off-by: Leo Yan <leo.yan at arm.com>
>> ---
>> drivers/hwtracing/coresight/coresight-etm4x-core.c | 15 ++++++++++++++-
>> 1 file changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/
>> drivers/hwtracing/coresight/coresight-etm4x-core.c
>> index 6a5898355a83..b12d59b89a49 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>> @@ -1820,6 +1820,11 @@ static int __etm4_cpu_save(struct etmv4_drvdata
>> *drvdata)
>> state = drvdata->save_state;
>> state->trcprgctlr = etm4x_read32(csa, TRCPRGCTLR);
>> +
>> + /* Stop the trace unit if it is enabled */
>> + if (state->trcprgctlr)
>
> etm4_cpu_save() looks at coresight_get_mode() to determine enabled
> state. Seems a bit inconsistent to look directly at the enable bit right
> after checking coresight_get_mode().
May be this is due to AUX pause case ? The mode could still be PERF, but
the ETM/ETE is disabled ?
>
>> + etm4_disable_trace_unit(drvdata);
>> +
>
> Section 3.4.1 in ARM IHI 0064H.b doesn't say that anything extra needs
> to be done here, and it implies that restoring to an enabled state
> should work. It might make sense to mention why it diverges from the
> published sequence. Or get the sequence updated? I suppose that document
> doesn't include ETE and I see there is one extra register missing from
> __etm4_cpu_save() which is written to in etm4_disable_trace_unit().
>
> Plus we end up doing extra things like two waits on TRCSTATR.PMSTABLE.
I guess, we need to stop the tracing before we reliably capture the
register states (similar to the disable/pause sequence).
Suzuki
>
>> if (drvdata->nr_pe)
>> state->trcprocselr = etm4x_read32(csa, TRCPROCSELR);
>> state->trcconfigr = etm4x_read32(csa, TRCCONFIGR);
>> @@ -1951,7 +1956,6 @@ static void __etm4_cpu_restore(struct
>> etmv4_drvdata *drvdata)
>> etm4_cs_unlock(drvdata, csa);
>> etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
>> - etm4x_relaxed_write32(csa, state->trcprgctlr, TRCPRGCTLR);
>> if (drvdata->nr_pe)
>> etm4x_relaxed_write32(csa, state->trcprocselr, TRCPROCSELR);
>> etm4x_relaxed_write32(csa, state->trcconfigr, TRCCONFIGR);
>> @@ -2035,6 +2039,15 @@ static void __etm4_cpu_restore(struct
>> etmv4_drvdata *drvdata)
>> /* Unlock the OS lock to re-enable trace and external debug
>> access */
>> etm4_os_unlock(drvdata);
>> +
>> + /*
>> + * Re-enable the trace unit if it was enabled before suspend.
>> + * Put it after etm4_os_unlock() as unlocking the OS lock is the
>> + * prerequisite for enabling the trace unit.
>> + */
>> + if (state->trcprgctlr)
>> + etm4_enable_trace_unit(drvdata);
>> +
>> etm4_cs_lock(drvdata, csa);
>> }
>
More information about the linux-arm-kernel
mailing list