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 */

Reply via email to