I dialed in my 9900k overclock years back on Windows, but just noticed that it’s not behaving the same on Fedora 35 (dual-boot). The initial observation was that the frequency is changing dynamically—I have it set to a static 5.1GHz in UEFI, which Windows doesn’t interfere with, but Linux apparently does. Further investigation with turbostat
reveals that the CPU is using low-power C-states, something else I turned off in UEFI. So the goal is to get Linux back in line.
Archwiki is helpful as always: CPU frequency scaling - ArchWiki
First thing was switching the idle driver from intel_idle
to acpi_idle
. The ACPI driver correctly sticks to C0/C1. However, this had no impact on the core clocks.
The best way I’ve found to monitor the CPU clock is this oneliner: watch -n.1 "grep \"^[c]pu MHz\" /proc/cpuinfo"
. The update rate is fast enough to see if the frequency is really stable, or if each core is just turbo-ing for a fraction of a second. This is the behavior at idle, kind of a turbo-boost round robin. Under load, all the cores briefly go to 5.1GHz (good!), then drop to 3.6GHz stable seconds later (bad!). The temps never get above 65-70C during this period.
Stuff I’ve tried:
- Changing frequency driver from
intel_pstate
toacpi-cpufreq
- I had to enable EIST to get the ACPI driver to work
Surprisingly, any change in behavior is minimal and I didn’t notice it
- Changing scaling governor from
powersave
toperformance
- Again, no real change that I noticed? Maybe something subtle.
- Tried with Intel and ACPI freq drivers
- Setting min/max scaling frequency
- Higher frequencies are clamped to 3.6GHz, so best I can do is 3.6–3.6GHz (instead of 0.8GHz–3.6GHz)
- Setting
ignore_ppc=1
- Really bummed about this one…was sure it would work. More details below.
With the Intel freq driver…no clue what the problem is. But if it ignores the C-states from the UEFI, it may as well ignore the CPU multiplier.
With the ACPI driver, I think I can tell what’s going on:
Summary
# cpupower frequency-info
analyzing CPU 0:
driver: acpi-cpufreq
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 10.0 us
hardware limits: 800 MHz - 3.60 GHz
available frequency steps: 3.60 GHz, 3.60 GHz, 3.40 GHz, 3.20 GHz, 3.00 GHz, 2.80 GHz, 2.60 GHz, 2.40 GHz, 2.20 GHz, 2.00 GHz, 1.80 GHz, 1.60 GHz, 1.40 GHz, 1.20 GHz, 1000 MHz, 800 MHz
available cpufreq governors: conservative ondemand userspace powersave performance schedutil
current policy: frequency should be within 3.60 GHz and 3.60 GHz.
The governor "performance" may decide which speed to use
within this range.
current CPU frequency: 3.60 GHz (asserted by call to hardware)
boost state support:
Supported: yes
Active: yes
The “hardware limits” line is suspicious, since it’s demonstrably false. I can trace these numbers back to /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
and scaling_min_freq
. Editing these files as root immediately changes the output of cpufreq
. However, it’s impossible to raise scaling_max_freq
to anything above 3601000 (~3.6GHz). It is writable by root—larger values are clamped.
This brings me to bios_limit
, a read-only file (even for root) in the same directory. It’s also set to 3601000. It seems like this number is driven by the _PPC
number in the ACPI spec, so that the mobo can throttle the CPU when it’s on battery vs AC power. But putting ignore_ppc=1
in my kernel commandline didn’t do anything, so maybe Linux is setting this number on its own. I verified that I didn’t typo it at the grub prompt by checking /sys/module/processor/parameters/ignore_ppc
(file equals 1
).
Any ideas? I wasn’t expecting it to be this tough to set a static frequency.