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]

Reply via email to