=== Collaborative Processor Performance Control (CPPC)

Contact: ShengYi Hung <aokblast@FreeBSD.org> +
Contact: Olivier Certner <olce@FreeBSD.org>

Collaborative Processor Performance Control (CPPC) is a standard introduced by ACPI to allow the OS to manage performance and, conversely, efficiency levels of CPUs thanks to an abstract performance scale in general uncorrelated to and more fine-grained than mere frequency levels.
Intel and AMD have been providing CPU implementations in support of ACPI CPPC for several years now.

FreeBSD had been supporting enabling CPPC but only for Intel processors and allowing to manage a useful but very limited subset of its functionality, thanks to the man:hwpstate_intel[4] driver added in 2020.
Hardware autonomous selection of the performance target depending on the workload is forcibly enabled, and only the main corresponding hardware tunable, called Efficiency/Performance Preference (EPP), is exported to the administrator via a man:sysctl[8] knob.

We have added support for AMD CPPC's implementation in the existing man:hwpstate_amd[4] driver which, contrary to man:hwpstate_intel[4], so far managed only "regular" P-states.
The driver exports 4 man:sysctl[8] knobs: Minimum performance, maximum performance, desired performance and EPP.
Minimum, maximum and desired performances are values between 0 and 255, but only a sub-range may have an effect depending on the hardware.
Initial values of minimum and maximum performances are set to the effective sub-range bounds as instructed by the platform (if available).
The EPP control serves to express a bias towards efficiency or performance, and is a value between 0 (maximum performance preference) and 255 (maximum efficiency preference).
The desired performance may be set to any value between minimum and maximum performance, or to the special value 0 to enable hardware autonomous selection of target performance by the hardware depending on the current workload.
The minimum performance, maximum performance and EPP controls apply regardless of whether autonomous selection is enabled or a specific desired performance specified.
Note that the effect of each combination of these values depend on the CPU model, and we have already been able to observe wildly different behaviors on a few ones.
Therefore, you should expect to have to experiment to find the values adapted to your use cases on a given machine.

man:hwpstate_amd[4] is included by the `GENERIC` kernel (through man:cpufreq[4]) and uses CPPC if the CPUs support it unless explicitly instructed otherwise (through the `machdep.hwpstate_amd_cppc_enable` tunable).
Consequently, in order to avoid performance regressions, for the time being we have decided to set the above-mentioned controls for maximum performance, as this is the default behavior for traditional P-state support and also that of any other man:cpufreq[4] driver except for man:hwpstate_intel[4] (which currently forces hardware autonomous selection and sets EPP to `0x80` (50%) by default).
This may be revised later depending on whether we can reliably determine if the running computer is a laptop.

Next steps are:

1. Modify man:hwpstate_intel[4] to be on par with man:hwpstate_amd[4]'s CPPC support in terms of functionality and default behavior.
   This includes:
   - Better error-handling and debugging output
   - Exporting knobs for all the above-mentioned controls
   - Change the scale of EPP (from percents to an 8-bit value)
   - Change the default values
1. Write a manual page for man:hwpstate_amd[4] (in the meantime, the explanations here and the embedded man:sysctl[8] knobs' documentation should be enough).
1. Teach man:powerd[8] the CPPC control knobs and some simple policies on how to set them.
1. Teach man:cpufreq[4] about the abstract performance values, to provide a unified interface to retrieve or set them.
1. Make man:cpufreq[4] support per-CPU settings.
1. Select default control values based on the platform type (probably from ACPI's ``FADT``'s `Preferred_PM_Profile` field).
1. Possibly move man:powerd[8] policies to kernel space.

Sponsor: The FreeBSD Foundation
