Re: [RESEND][PATCH 0/3] ACPI: CPPC: Reduce .target() callback overhead
"Rafael J. Wysocki (Intel)" <[email protected]> Thu, 6 Aug 2026 12:36:27 +0200
| Newsgroups | gmane.linux.kernel,gmane.linux.power-management.general,gmane.linux.acpi.devel |
|---|---|
| Message-ID | <CAJZ5v0hkE708Qn5rX26X9i1+tGgoYOYyBmoc0zUw4N7m=r8m3w@mail.gmail.com> |
On Thu, Aug 6, 2026 at 12:05 PM Christian Loehle <[email protected]> wrote: > > On 8/3/26 23:28, Christian Loehle wrote: > > On 8/3/26 22:05, Christian Loehle wrote: > >> 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/[email protected]/ > >> > >> and the separately posted fix still under review: > >> https://lore.kernel.org/lkml/[email protected]/ > >> > >> 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/[email protected]/ > >> > >> [RESEND] for the new base-commit specifier below > >> > >> 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: 075b74841bd0065a3bda3440873c747938e69b68 > > > > Nice, so that worked: > > https://sashiko.dev/#/patchset/[email protected] > > Seems no findings on $SUBJECT but the rest of the comments it has > > look legit to me? I'll go take another look tomorrow: > > So I have patches for these all and will post them in a minute. > > > > > 1. Using per-CPU cpc_desc->rmw_lock for SYSTEM_MEMORY CPPC control register that > > may be shared. > > The solution here sucks unfortunately. > Obviously expanding the per-CPU rmw_lock to per-policy is reasonable, but unfortunately > that doesn't prevent something like: > Policy 0 Desired: address X, bits 7:0, access size 32 > Policy 1 Desired: address X, bits 15:8, access size 32 > which would be a compliant GAS description and would require a global lock for rmw. > > And of course even worse, now that Desired is write-only rmw isn't possible at all > anymore. > I'm leaning to just reject these edge-cases that hopefully don't actually exist > (and require _CPC rev4 to be full access-unit width) > Opinions? Fail initialization on insane platform setups I'd say. There's no promise that Linux will support compliant setups that are too much pain to deal with.