Maximising AMD Ryzen CPU performance in Linux

If you haven't "Ryzen" with a state of P, you should.

As of Linux Kernel 5.18, P-state for CPUs is now supported and depending on your CPU and your distribution of linux, it may or may not be automatically enabled. But what does this mean for you, especially, if you own a Ryzen CPU? Or rather, what is P-state? Consider P-states as different power profiles for your CPU which the OS can trigger to either run the CPU at higher clock speeds for demanding workloads or just scale down and run at lower clock speeds to save power (which is especially important for laptops to conserve battery life). If you want the finer details you can read more here.

So let’s get back to the focus of this piece. ***How do you use the new kernel features to maximise the performance of your Ryzen based system? ***

Hinweis / Notice: * I’m using Fedora 37 Workstation with the 6.1.6
kernel. If your distro is yet to provide this kernel version, you may want to wait or take the risks of kernel patching (i.e. Ubuntu and derivatives, kernel patching can break your system if anything goes wrong. For others, such as Fedora, Arch based distros, OpenSUSE it should be fine). *

Preliminaries: BIOS settings

Before you begin, make sure to check that these settings in your BIOS are **enabled. (**Some motherboards tend to disable some or all of the below and if it is in your case, just enable it.). You can find them inside Advanced CPU configuration or AMD CBS Menu.

  • Global C-state control

  • CPPC

  • CPPC Preferred Core

And yes, if you’re not overclocking your CPU, do definitely enable PBO(Precision Boost Overdrive).

Inside Linux

Install kernel-tools

Use the package manager of your distro to install the kernel-tools package (or however they named it for your distro).

Check if P-state is already enabled

sudo cpupower frequency-info | grep driver

If the output does not show the following then you don’t have P-state automatically enabled.

driver: amd-pstate

Check CPU capabilities

There are two ways the new kernel handles the CPU P-state, with full MSR support or via Shared Memory Model. You’ve to find out first which one your CPU supports.

lscpu | grep cppc

If you don’t see any output, then your CPU supports the shared memory model.

Update GRUB

In this case you’ve to add a modifier flag to GRUB, the bootloader. Open the grub config to edit it:

sudo nano /etc/default/grub

There, have the GRUB_CMDLINE_LINUX, which looks like this on my system:

GRUB_CMDLINE_LINUX="rd.driver.blacklist=nouveau modprobe.blacklist=nouveau nvidia-drm.modeset=1 initcall_blacklist=simpledrm_platform_driver_init rhgb quiet rd.driver.blacklist=nouveau modprobe.blacklist=nouveau nvidia-drm.modeset=1 initcall_blacklist=simpledrm_platform_driver_init"

What you have to do here is that at the end of the string (still inside the “”) add the following:

amd_pstate.shared_mem=1 amd_pstate=passive

Now the variable should look like this:

GRUB_CMDLINE_LINUX="rd.driver.blacklist=nouveau modprobe.blacklist=nouveau nvidia-drm.modeset=1 initcall_blacklist=simpledrm_platform_driver_init rhgb quiet rd.driver.blacklist=nouveau modprobe.blacklist=nouveau nvidia-drm.modeset=1 initcall_blacklist=simpledrm_platform_driver_init amd_pstate.shared_mem=1 amd_pstate=passive"

Once done, update grub according to the instructions of your distro and reboot your computer. For Fedora, you can find the instructions here.

Verify if P-state is enabled

Once your computer boots back into linux, run the following command to see if all the changes have taken effect.

sudo cpupower frequency-info | grep driver

The expected output should be:

driver: amd-pstate

Check frequency scaling policy

The frequency scaling policy determines which power profile will be used for your CPU.

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

In many distros, the default is to use schedutil . However if you’re on a desktop as me, and conserving batter isn’t a concern, you can switch this to performance.

sudo cpupower frequency-set -g performance

cpupower frequency info

Once done, check how the scaling will be done for your cpu

sudo cpupower frequency-info

On my system (Ryzen 9 3950X) it shows the following:

analyzing CPU 0:
  driver: amd-pstate
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 131 us
  hardware limits: 550 MHz - 4.76 GHz
  available cpufreq governors: conservative ondemand userspace powersave performance schedutil
  current policy: frequency should be within 550 MHz and 4.76 GHz.
                  The governor "performance" may decide which speed to use
                  within this range.
  current CPU frequency: Unable to call hardware
  current CPU frequency: 4.40 GHz (asserted by call to kernel)
  boost state support:
    Supported: yes
    Active: yes
    AMD PSTATE Highest Performance: 166. Maximum Frequency: 4.76 GHz.
    AMD PSTATE Nominal Performance: 122. Nominal Frequency: 3.50 GHz.
    AMD PSTATE Lowest Non-linear Performance: 61. Lowest Non-linear Frequency: 1.75 GHz.
    AMD PSTATE Lowest Performance: 20. Lowest Frequency: 550 MHz.

One minor issue though ...

What I've found is that cpupower reverts back to default on each boot. Which means you've to run the command manually. I find that kind of inefficient. So an easy solution would be to enable the cpupower systemd-service and modify it.

sudo systemctl enable cpupower.service
sudo systemctl start cpupower.service --now

Now add the slight edit in the service file

sudo nano /lib/systemd/system/cpupower.service

Inside, change the ExecStart variable to the following.

ExecStart=/usr/bin/cpupower frequency-set -g performance

Once done, save the edits, and reload all daemons.

sudo systemctl daemon-reload

That’s it

The frequency scaling via cpupower can also be done through GNOME power settings as well. However it also depends on your distro if they’ve integrated all the features. So that’s it. You can now get the most out of your Ryzen CPU with proper OS controlled boosting.