This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 9fdadb4dae2f793408e5d8b97b27d93e711f7786 Author: Marco Casaroli <[email protected]> AuthorDate: Tue Nov 3 19:43:19 2026 +0100 arch/arm64: Start the PMU cycle counter on the secondary CPUs. The boards call up_perf_init() once, on the boot CPU. But the cycle counter (PMCCNTR_EL0) and its control registers belong to each CPU, so the counter of the other CPUs does not run. With SMP, perf_gettime() on CPU 1 to N returns a constant: the critmon times and the CPU-time clocks of the threads on those CPUs stay 0. Start the cycle counter of each secondary CPU in arm64_boot_secondary_c_routine(), with the same condition (ARCH_PERF_EVENTS) as the call of up_perf_init(). The cluster PMU is common to the CPUs, so the secondary CPUs do not start it again. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- arch/arm64/src/common/arm64_cpustart.c | 4 ++++ arch/arm64/src/common/arm64_perf.c | 41 +++++++++++++++++++++++++++++----- arch/arm64/src/common/arm64_smp.h | 13 +++++++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c index 42a41c7fe36..39786a67ce3 100644 --- a/arch/arm64/src/common/arm64_cpustart.c +++ b/arch/arm64/src/common/arm64_cpustart.c @@ -236,5 +236,9 @@ void arm64_boot_secondary_c_routine(void) arm64_timer_secondary_init(); +#ifdef CONFIG_ARCH_PERF_EVENTS + arm64_perf_secondary_init(); +#endif + arm64_smp_init_top(); } diff --git a/arch/arm64/src/common/arm64_perf.c b/arch/arm64/src/common/arm64_perf.c index 509c983c0d6..952d2efa50d 100644 --- a/arch/arm64/src/common/arm64_perf.c +++ b/arch/arm64/src/common/arm64_perf.c @@ -27,6 +27,7 @@ #include <nuttx/clock.h> #include "arm64_pmu.h" +#include "arm64_smp.h" #ifdef CONFIG_ARCH_HAVE_PERF_EVENTS @@ -37,6 +38,21 @@ static unsigned long g_cpu_freq = ULONG_MAX; +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifndef CONFIG_ARCH_CLUSTER_PMU +static void arm64_perf_start(void) +{ + pmu_ccntr_ccfiltr_config(PMCCFILTR_EL0_NSH); + pmu_cntr_control_config(PMCR_EL0_C | PMCR_EL0_E); + pmu_cntr_trap_control(PMUSERENR_EL0_EN); + pmu_cntr_irq_disable(PMINTENCLR_EL1_C); + pmu_cntr_enable(PMCNTENSET_EL0_C); +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -52,14 +68,29 @@ void up_perf_init(void *arg) pmu_clucntr_irq_disable(CLUSTERPMINTENCLR_EL1_C); pmu_clucntr_enable(CLUSTERPMCNTENSET_EL1_C); #else - pmu_ccntr_ccfiltr_config(PMCCFILTR_EL0_NSH); - pmu_cntr_control_config(PMCR_EL0_C | PMCR_EL0_E); - pmu_cntr_trap_control(PMUSERENR_EL0_EN); - pmu_cntr_irq_disable(PMINTENCLR_EL1_C); - pmu_cntr_enable(PMCNTENSET_EL0_C); + arm64_perf_start(); #endif } +/**************************************************************************** + * Name: arm64_perf_secondary_init + * + * Description: + * Start the cycle counter of a secondary CPU. up_perf_init() runs on + * the boot CPU only, and the cycle counter is a register of each CPU. + * The cluster PMU is common to the CPUs: it is already started. + * + ****************************************************************************/ + +#ifdef CONFIG_SMP +void arm64_perf_secondary_init(void) +{ +#ifndef CONFIG_ARCH_CLUSTER_PMU + arm64_perf_start(); +#endif +} +#endif + unsigned long up_perf_getfreq(void) { return g_cpu_freq; diff --git a/arch/arm64/src/common/arm64_smp.h b/arch/arm64/src/common/arm64_smp.h index 90082d3e95a..7909d870776 100644 --- a/arch/arm64/src/common/arm64_smp.h +++ b/arch/arm64/src/common/arm64_smp.h @@ -93,6 +93,19 @@ void arm64_enable_smp(int cpu); void arm64_timer_secondary_init(void); +/**************************************************************************** + * Name: arm64_perf_secondary_init + * + * Description: + * Start the PMU cycle counter of a secondary CPU. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm64_perf_secondary_init(void); + #endif /* __ASSEMBLY__ */ #endif /* CONFIG_SMP */ #endif /* __ARCH_ARM64_SRC_COMMON_ARM64_SMP_H */
