The Ubuntu 18.04 CPU Frequency Governor Fix

So before, in Ubuntu 16.04 and below, /etc/init.d/ondemand was responsible for changing the CPU frequency to “ondemand” which caused issues while gaming with the processor downclocking. This is why Feral Interactive created Linux “GameMode” which sets the frequency governor to “performance”

Trouble is, the fix is extremely simple… Just change echo -n ondemand > $CPUFREQ to echo -n performance > $CPUFREQ

Ubuntu 18.04 relocated this script to instead of being in /etc/init.d/ondemand to instead be a script that is called upon by a ondemand.service in /lib/systemd/set-cpufreq

A glance at /lib/systemd/set-cpufreq makes it look practically identical to the previous /etc/init.d/ondemand!

How do we set the CPU Governor to “performance?”

Make /lib/systemd/performance.patch with this as the contents:

--- set-cpufreq	2018-11-24 06:12:29.696495541 -0800
+++ set-cpufreq_perf	2018-11-24 06:03:48.351162000 -0800
@@ -34,12 +34,12 @@
 
 [ -n "${GOVERNOR:-}" ] || exit 0
 
-echo "Setting $GOVERNOR scheduler for all CPUs"
+echo "Setting performance scheduler for all CPUs"
 
 for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
 do
         [ -f $CPUFREQ ] || continue
-        echo -n $GOVERNOR > $CPUFREQ
+        echo -n performance > $CPUFREQ
 done
 if [ -n "${SAMPLING:-}" ] && [ -f $DOWN_FACTOR ]; then
         echo -n $SAMPLING > $DOWN_FACTOR

Patch the file with patch -N -r /dev/null < performance.patch, then reboot.

To make the setting stick, you have to create a startup script that applies this patch every boot. Systemd updates will always overwrite the file back to default values despite file permissions you set to the file.

That’s literally it.

Once again, modify /lib/systemd/set-cpufreq with the patch file, then patch the file each boot with a startup script to change the governor in 18.04. systemd startup service instructions in post 8. (The post marked as the solution)

If you have a symlink for /lib, please change all references of /lib to /usr/lib as a precaution.

3 Likes

Interesting :slight_smile:
Think you might be able to stuff that into Feral’s face? :wink:

It’s different on Fedora. That uses a completely different script: (supposed to be in /etc/init.d/performance)

#! /bin/bash
#
# performance sets cpu governor
#
# chkconfig: 2345 10 90
#
# description: Set the CPU Frequency Scaling governor to "performance"
#
### BEGIN INIT INFO
# Provides: $performance
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin

case "$1" in
    start)
        for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
        do
                [ -f $CPUFREQ ] || continue
                echo -n performance > $CPUFREQ
        done
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop)
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

Then:

chmod +x /etc/init.d/performance
chkconfig performance on
service performance restart

The last one verifies it returns the error you wrote into the script and that it’s actually working.

( adapted from https://www.servernoobs.com/avoiding-cpu-speed-scaling-in-modern-linux-distributions-running-cpu-at-full-speed-tips/ )

1 Like

UPDATED

systemd updates will overwrite the file with default values, meaning system responsiveness will return to a sluggish state if a systemd update is allowed to touch all files. You must set the file in this guide to read-only to POTENTIALLY prevent the update from touching it. Otherwise, it’s back to the crap ondemand CPU governor, which doesn’t work for DXVK.

3 Likes

I thought we wouldn’t need this if we’re manually over clocked? Or did I miss something?

Some time back I noticed that CPU frequency still varied in fedora, even when I overclocked my Ryzen 1600. I have an overclock in BIOS to 3.8 GHz but when I check with cat /proc/cpuinfo it downclocked to 1.37 GHz when I don’t do anything. Pretty neat :slightly_smiling_face:. Maybe the frequency changes cause stability issues for some people. For me it’s perfectly stable.

That’s cause you are using a powersave or ondemand CPU governor. This has a severe performance detriment to DXVK and Vulkan titles. DXVK recommends you always stay on performance governor.

The Kernel ignores C-state info from the BIOS and just applies a C-state on it’s own. You want to make sure your minimum C-state don’t enter the deep sleep states, but also that the CPU governor takes advantage of the full turbo frequency. For DXVK and Vulkan, if you set 4.6Ghz, powersave or ondemand only clocks as high as 4.2Ghz. You lose a lot of performance.

Well, setting the file to read-only doesn’t work. You basically need a startup script to patch that set-cpufreq file on every boot to ensure it’s applied properly, as systemd updates override any read only flags you might set.

I provided a performance.patch in the original post. Scroll up to get the contents of the .patch file.

You need to make a /etc/performance.sh:

#!/bin/bash
patch -N -r /dev/null -f /lib/systemd/set-cpufreq /lib/systemd/performance.patch

And then that has to run with elevated privileges every boot using systemd.

Make a systemd service in /etc/systemd/system/performance.service:

[Unit]
Description=Change CPU Governor to Performance

[Service]
Type=oneshot
ExecStart=/etc/performance.sh
User=root
Group=root
SuccessExitStatus=0 1

[Install]
WantedBy=multi-user.target

Then:

sudo chmod +x /etc/performance.sh
sudo systemctl enable performance
sudo systemctl start performance

and reboot.

Edit January 2022: If you are using a distro where /lib is a symlink:

Change all /lib links to /usr/lib as a precaution. Also make sure you are saving the patch file in /usr/lib/systemd and not /usr/lib/systemd/system as is usual when creating a .service. Easy mistake to make when you’re dealing with making this systemd service.

1 Like

We should make this into a GitHub/GitLab repo.

Currently #2 on DDG


Another probably much more simpler solution is to use tuned package. Should be the exact same for 18.04 and 19.10.

sudo apt install -y tuned
sudo systemctl enable tuned
sudo systemctl start tuned
sudo tuned-adm profile throughput-performance

https://packages.ubuntu.com/eoan/tuned

Yes, but that’s relying on Canonical providing for a fix to a problem that they themselves want to always set the governor to ondemand via a systemd service on every systemd upgrade, so you can’t 100% trust that they won’t suddenly change to remove governor changing options. This relies on nothing from Canonical and is independent of Canonical.

tuned and tuned-adm sounds a lot like Feral GameMode. I believe @wendell just removes irqbalance to enhance performance without GameMode or tuned. You can then manually make the governor performance from there.

Tuned is what we use on servers. But yeah the down clocking thing is annoying. It’s the simplest thing I could think of at the time. I tried your solution but it’s unclear and failed to work. Needs refinement.

At first I didn’t even realize it was happening but once I started doing workloads that took several hours I found this out and it’s unacceptable.

The .patch file is in the first post, and the rest of the instructions is in the solution post.

This is an alternate method that seems to work, not sure about any advantages/disadvantages, but figured it might be useful. Since I’m very new, I’ll write for someone equally as inexperienced. Obviously credit to FurryJackman fo the bulk of the ideas.

It uses the cpupower tool which can be obtained by installing the following:

sudo apt install linux-tools-common
sudo apt install linux-tools-generic

This nice utility can set the cpu governor, as well as displaying info. So create a script that does that.

sudo nano /etc/performance.sh

In that file type

#!/bin/bash
#uses cpupower tool to set cpu frequency governor to performance
cpupower frequency-set -g performance

Ctrl+o to save
Ctrl+x to exit

Make it executable

sudo chmod +x /etc/performance.sh

Create a service to run it at boot

sudo nano /etc/systemd/system/performance.service

[Unit]
Description=Set cpu governor to performance

[Service]
Type=oneshot
ExecStart=/etc/performance.sh
User=root
Group=root
SuccessExitStatus=0 1

[Install]
WantedBy=multi-user.target

Ctrl+o to save
Ctrl+x to exit

Enable and start it

sudo systemctl enable performance
sudo systemctl start performance

Then to stop the governor reverting disable the ondemand service (neater)

sudo systemctl disable ondemand.service

Or delete /lib/systemd/cpu-freq (messier)

sudo rm /lib/systemd/cpu-freq

Reboot.
To check it worked you can use

cpupower frequency-info

Under current policy it should say performance.
Hope this is useful to someone.

2 Likes

I just came back around to this thread setting up 20.04.1 and I see that I never answered this:

systemd files and conditions resetting with systemd upgrades is why I use the patch file, because ondemand.service will just be reset to enabled after an update should you disable it, and deleting the file will only have it re-appear with the same systemd update.

The condition I set for the service when I wrote it will not throw an error when the patch is already applied or if the patch is successful. This is generally not good practice, but for using diff and patch at boot, this is what I had to do to silence error messages. It does apply correctly after each systemd update so the exit code doesn’t matter if it works.

Combine the instructions in post 1 and post 8 to get where you need to go. It still works in 20.04.1 too, but make sure to check if /lib is a symlink in your distro.

Big bump.

You aren’t necessarily tied to putting performance.sh in /etc. You can put it in /opt and change the paths to opt no problem too.

See posts 1 and 8 on updated guidance if your /lib is a symlink in your distro.