cppc-cpufreq reaches cppc_set_perf() from every target callback. For
direct SystemMemory controls, that path currently does several steps
which are unnecessary once the immutable _CPC layout is known:
- a full-width write first reads the access unit and merges the value.
- every write takes the descriptor's RMW lock, even when its access unit
is not shared with another _CPC entry.
- cppc_set_perf() evaluates the same three PCC predicates at each phase
of the transaction.
Remove those costs while retaining the existing conservative paths for
partial fields, overlapping or malformed access units, and PCC controls.
The series was tested on Arm Power-Orion O6 and AmpereOne systems using
cppc-cpufreq and schedutil. An rt-app task pinned to one CPU ran for
500 us every 2 ms with uclamp.min=512, for 5000 periods per run. schedutil
rate_limit_us was 1000. cppc_cpufreq_fast_switch() latency was measured
for 100 ten-second runs. Each sample is the mean callback latency within
one run, and the table reports the median and sample standard deviation
of those samples.
Orion O6 median stdev callbacks
baseline 5703 ns 307 ns 188017
complete series 5023 ns 240 ns 188209
==> 680 ns (11.9%) reduction
AmpereOne median stdev
baseline 2090 ns 157 ns
complete series 1907.5 ns 140 ns
==> 182.5 ns (8.7%) reduction
The cumulative intermediate results on the Orion O6 attribute roughly half
of the gain to each of the first two patches: avoiding the read reduced
the median by 284 ns (5.0%), and avoiding the lock reduced it by another
336 ns (6.2%).
Together they account for 620 ns of the 680 ns total reduction.
With the same arm64 configuration and GCC 11.4, caching the PCC predicate
also reduces cppc_set_perf() from 1124 to 884 bytes. The generated
function has 60 fewer instructions, 17 fewer loads and 20 fewer branches.
This series is based on the CPPC fixes posted at (already queued):
https://lore.kernel.org/lkml/20260722093825.1030594-1-christian.loehle@arm.com/
and the separately posted fix still under review:
https://lore.kernel.org/lkml/20260724104042.1481804-1-christian.loehle@arm.com/
PS:
There's a final optimization that I actually wanted to make but decided to
split it out for now as it somewhat replicated Sumit's series:
Skipping redundant perf ctrl writes in cpufreq-cppc if registers are non-PCC
and !shared (because the values are unchanged, the
!autonomous-common-case), but that requires the driver to have a more
complex caching- and atomic-updating machinery in place, similar to
hotplug. As opposed to this series the optimization would be for the
microcontroller handling the CPPC requests, which may be shared across
many CPUs and therefore redundant requests can increase the dvfs
transition latency.
That patch will follow once Sumit's is queued:
https://lore.kernel.org/lkml/20260716153820.2007095-1-sumitg@nvidia.com/
Christian Loehle (3):
ACPI: CPPC: Avoid unnecessary reads for full-width writes
ACPI: CPPC: Avoid locking standalone full-width registers
ACPI: CPPC: Evaluate performance-control PCC use once
drivers/acpi/cppc_acpi.c | 135 +++++++++++++++++++++++++++++++--------
include/acpi/cppc_acpi.h | 5 +-
2 files changed, 113 insertions(+), 27 deletions(-)
base-commit: 1590cf0329716306e948a8fc29f1d3ee87d3989f
prerequisite-patch-id: 4c1f4063800e3658717eb77e43af13dad52d55cc
prerequisite-patch-id: 5c40d9f099543123c9b904d18ce651e740fbefb8
prerequisite-patch-id: 7202391dca8f31f9eb8f6d59fc753b3ce665e103
--
2.34.1