casaroli opened a new pull request, #21732: URL: https://github.com/apache/nuttx/pull/21732
depends-on: apache/nuttx/pull/21729 ## Summary `up_perf_gettime()` on arm64 reads the PMU cycle counter (`PMCCNTR_EL0`). It is a register of each CPU, and each CPU starts it at a different time. On `qemu-armv8a:nsh_smp` the counters of the secondary CPUs are about 3 ms behind CPU 0. The critical section monitor subtracts a time of one CPU from a time of another CPU (the run time and the CPU load of a thread that moves to another CPU), so with SMP these values are wrong. With SMP, `up_perf_gettime()` now reads `CNTVCT_EL0`, the counter of the generic timer, which is the same on all CPUs, and `up_perf_getfreq()` returns `CNTFRQ_EL0`. With `CONFIG_ARCH_HAVE_PERF_EVENTS_USER_ACCESS` (Cortex-R82 without the cluster PMU) a non-flat build also has a user space `up_perf_gettime()`, so each CPU sets `CNTKCTL_EL1.EL0VCTEN` to let EL0 read the counter, as it now enables the PMU cycle counter for EL0. Without SMP, and with `CONFIG_ARCH_CLUSTER_PMU` (one counter for the cluster), nothing changes. ## Impact - arm64 with SMP and `CONFIG_ARCH_PERF_EVENTS`: perf times have the resolution of the generic timer (`CNTFRQ_EL0`, 24 MHz on QEMU) instead of CPU cycles. They are the same on all CPUs. - No Kconfig, API or documentation change. ## Testing Test program `tcpumono -c`: a thread pinned to each CPU reads `up_perf_gettime()` between two reads of `CNTVCT_EL0` and prints the offset of the CPU's perf time from CPU 0. `qemu-armv8a:nsh_smp` (flat, 4 CPUs, QEMU HVF, `ARCH_PERF_EVENTS`, `SCHED_CPULOAD_CRITMONITOR`), 3 rounds: | | master 59cb24ea20c | this PR | |---|---|---| | CPU 1 minus CPU 0 | -3390791 ns | -42 to -84 ns | | CPU 2 minus CPU 0 | -2838083 ns | 0 to -1 ns | | CPU 3 minus CPU 0 | -3624208 ns | 0 to -125 ns | | ostest | status 0 | status 0 | The values of this PR are within the time of one read (up to 250 ns). `qemu-armv8a:knsh` with 4 CPUs (kernel build, `ARCH_PERF_EVENTS`): ostest status 0 with master and with this PR. The EL0 read of `CNTVCT_EL0` was built, not run: no board configuration has a Cortex-R82 with SMP in a protected or kernel build. Builds with `-Werror`, no warning: `qemu-armv8a:nsh` (no SMP: PMU, no change), `fvp-armv8r:nsh_smp` (`CNTVCT_EL0`) and `fvp-armv8r:nsh_smp` with `CONFIG_ARCH_CLUSTER_PMU` (cluster PMU, no change). `tools/checkpatch.sh -c -u -m -g` passes. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
