GameMode is a new daemon/lib combo for Linux that will allow you to optimize your PC for gaming. It’s not magic, it won’t suddenly make your Linux games suddenly get better performance, but it’s something that can help.
You might have seen a message box pop up with some more recent Linux ports from Feral Interactive, one that tells you that your current CPU governor is not optimised—like this:
When games end up waiting on the GPU, some CPU performance governors may downclock the CPU and then up it again later, which can result in performance problems. GameMode, as it is right now, is to help you with that. Curious about it and wanting to know a little more direct from the developers, Feral agreed to answer some quick questions I had about it:
1) Can you give us a rundown on what exactly GameMode is and why Linux gamers might need it?
“GameMode is a daemon/library combo for Linux, written in C, which allows games to request that a set of optimisations be temporarily applied to the host OS. These optimisations improve the performance of the game.
To apply these optimisations, some of our games require that users manually swap the CPU governor using sudo privileged commands. We've had some feedback from people saying that they'd prefer not to have to do so much setup in order to get the best performance from their game. Further to this, some users voiced concerns about the increased energy usage that might result from leaving the CPU in a higher power usage mode.
By automatically applying these optimisations when the game is running and removing them when it isn't, GameMode saves users the trouble of having to tinker. It also ensures that the CPU is restored to a more efficient state when they've finished playing.”
2) You say it is "intended to be expanded beyond just CPU governor states", what extras did you have in mind?
“A lot of good ideas have been put forward by beta testers, including de-activating tools like f.lux, swapping KWin from OpenGL to xrender, and changing users' chat client status to "Playing X". GameMode is Open Source, so pull requests, or forks with features like these are welcome.”
3) To be clear for our readers, is this something that will ship built-in with Feral games and will users have to do any manual steps to enable it?
“GameMode won't ship with the games; since it's open source, users will need to install it themselves using the steps on GitHub. The tool will only need to be installed once, and will work with all future Linux titles released by Feral.
It will also work with previously released games, provided users adjust their launch options on Steam.”
It’s currently under a “BSD 3-Clause License (Revised)” license and you can find out more on GitHub. It’s certainly going to be interesting to see how this project evolves over time, could end up being something extremely useful. It already made its way to the AUR for Arch users.
Once you've installed it using their instructions, you can then tell any game to use it by doing this command:
LD_PRELOAD=/usr/\$LIB/libgamemodeauto.so ./game
You can also add it as a Steam launch option for each of your games like so:
LD_PRELOAD=$LD_PRELOAD:/usr/\$LIB/libgamemodeauto.so %command%
If you wish to know what current CPU governor is in use, you can run this command in terminal:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
I actually had pre-announcement access to it and testing it has given me some good early results. Obviously this will be game and hardware dependent and yes, all tests were done over multiple runs to ensure it wasn't a fluke.
Testing it with F1 2017 for example, gave these FPS results:
That might not look like a big difference, however, behind the FPS results are the frame timings:
Without Game Mode | With Game Mode | |
---|---|---|
Min Frame Time | 10.32ms | 10.03ms |
Average Frame Time | 13.31ms | 11.88ms |
Max Frame Time | 19.36ms | 16.02ms |
As you can see, it has helped to reduce frame timings while increasing the overall framerate, so using GameMode (or manually using performance mode) can have an impact resulting in a smoother game. Using GameMode instead of doing it manually, does have the benefit of your CPU reverting to a more power efficient mode afterwards of course.
Testing Deus Ex: Mankind Divided was a slightly different story, as it always gave a better minimum FPS score when using GameMode, but the average and maximum showed little difference—certainly still worth it though! As for frame timings, the built-in benchmark doesn't give them.
Company of Heroes 2 is similar to Deux Ex with the benchmark mode only giving FPS scores. During my testing, both in the benchmark mode and actually playing it, the difference was noticable when using GameMode—with it being much smoother overall:
Again, to stress, your results will depend on your hardware and it's no different to manually changing your CPU governor to performance—for now (until they do more with it), although it does bring it back down to powersave or ondemand automatically which is nice.
Rise of the Tomb Raider will be the first game from Feral to have support for it integrated, so you won't need to give it any special launch options. However, you still need to install the tool yourself.
It’s great to see Feral Interactive do more open source projects, as they already have their game launcher scripts up on GitHub too.
I found a simple suid program on the net, which I just had to change a bit to do the right things.
How do you set the resulting binary? I tried making it owned by root:root and then giving it setuid flag, but it still fails when setuid is called from it.
I found a simple suid program on the net, which I just had to change a bit to do the right things.
How do you set the resulting binary? I tried making it owned by root:root and then giving it setuid flag, but it still fails when setuid is called from it.
As you said it has to be owned by root, then
sudo chmod u+s binary
That works for me.
Edit: I guess I will be using Ferals programm sooner or later anyway. I just don't like running root daemons without even having the time to read the source code.. or better, having some security experts reading the sourcecode. Don't get me wrong, I do trust Feral, but a daemon is in a delicate position, and even small flaws can be exploited.
Last edited by Nevertheless on 11 April 2018 at 7:09 am UTC
Good but I would prefer not to install anything. Could we simply run a command before and after playing?
I found a simple suid program on the net, which I just had to change a bit to do the right things.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 );
system( "echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor" );
return 0;
}
and to set it back to powersave:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 );
system( "echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor" );
return 0;
}
This is really bogus, broken code ...
The setuid command is useless since
- a) you are already root (per chmod u+s)
- b) you would not be able to elevate your privileges like that if you were not. That would be a security hole. The purpose of setuid is to drop privileges when you are already root. Not to elevate them (see man setuid).
Using sudo in the system commandline makes no sense as well. It is benign if you have a setuid root binary (i.e. does nothing, just leave it out). If you are not yet root it will ask of course but then you can really just use the commandline directly. Skip the c and use bash.
Good but I would prefer not to install anything. Could we simply run a command before and after playing?
I found a simple suid program on the net, which I just had to change a bit to do the right things.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 );
system( "echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor" );
return 0;
}
and to set it back to powersave:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 );
system( "echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor" );
return 0;
}
This is really bogus, broken code ...
The setuid command is useless since
- a) you are already root (per chmod u+s)
- b) you would not be able to elevate your privileges like that if you were not. That would be a security hole. The purpose of setuid is to drop privileges when you are already root. Not to elevate them (see man setuid).
Using sudo in the system commandline makes no sense as well. It is benign if you have a setuid root binary (i.e. does nothing, just leave it out). If you are not yet root it will ask of course but then you can really just use the commandline directly. Skip the c and use bash.
Oops, yes, sorry, pasted the wrong file. Strike the sudo! It doesn't hurt, but it's absolutely not needed.
Setuid is used in a lot of cases to elevate privileges. In mount, umount, su, sudo for example. In this case it gives me exactly what I want: I can switch the governor without having to provide a password. It does nothing more. So I don't see any risk.
Don't seem to work for me, downloaded from AUR, when i try:
LD_PRELOAD=/usr/\$LIB/libgamemodeauto.so ./name of game/benchmark
i get from terminal:
gamemodeauto: Could not call method on bus: No route to host
gamemodeauto: Could not call method on bus: No route to host
gamemodeauto: Could not call method on bus: No route to host
I just tested it on Arch with the AUR package. Works fine for me.
Have you enabled and started the user daemon?
systemctl --user enable gamemoded
systemctl --user start gamemoded
systemctl --user status gamemoded
Edit: I guess I will be using Ferals programm sooner or later anyway. I just don't like running root daemons without even having the time to read the source code.. or better, having some security experts reading the sourcecode. Don't get me wrong, I do trust Feral, but a daemon is in a delicate position, and even small flaws can be exploited.
It's not a root daemon. It runs as a normal user using systemds usermode and polkit.
Edit: I guess I will be using Ferals programm sooner or later anyway. I just don't like running root daemons without even having the time to read the source code.. or better, having some security experts reading the sourcecode. Don't get me wrong, I do trust Feral, but a daemon is in a delicate position, and even small flaws can be exploited.
It's not a root daemon. It runs as a normal user using systemds usermode and polkit.
And how does it apply CPU governor changes?
Edit: I guess I will be using Ferals programm sooner or later anyway. I just don't like running root daemons without even having the time to read the source code.. or better, having some security experts reading the sourcecode. Don't get me wrong, I do trust Feral, but a daemon is in a delicate position, and even small flaws can be exploited.
It's not a root daemon. It runs as a normal user using systemds usermode and polkit.
And how does it apply CPU governor changes?
By using Polkit. I think it also logs something about executing pkexec. Start the daemon and follow the logs with 'journalctl -f --user-unit gamemoded'.
Last edited by OlliC on 11 April 2018 at 11:36 am UTC
Edit: I guess I will be using Ferals programm sooner or later anyway. I just don't like running root daemons without even having the time to read the source code.. or better, having some security experts reading the sourcecode. Don't get me wrong, I do trust Feral, but a daemon is in a delicate position, and even small flaws can be exploited.
It's not a root daemon. It runs as a normal user using systemds usermode and polkit.
And how does it apply CPU governor changes?
By using Polkit. I think it also logs something about executing pkexec. Start the daemon and follow the logs with 'journalctl -f --user-unit gamemoded'.
Interesting! Thanks for the info!
Good but I would prefer not to install anything. Could we simply run a command before and after playing?
I found a simple suid program on the net, which I just had to change a bit to do the right things.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 );
system( "echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor" );
return 0;
}
and to set it back to powersave:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
setuid( 0 );
system( "echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor" );
return 0;
}
This is really bogus, broken code ...
The setuid command is useless since
- a) you are already root (per chmod u+s)
- b) you would not be able to elevate your privileges like that if you were not. That would be a security hole. The purpose of setuid is to drop privileges when you are already root. Not to elevate them (see man setuid).
Using sudo in the system commandline makes no sense as well. It is benign if you have a setuid root binary (i.e. does nothing, just leave it out). If you are not yet root it will ask of course but then you can really just use the commandline directly. Skip the c and use bash.
I forgot about the "setuid( 0 );" in the file. It's nessessary. Try for yourself (with owner root and suid root):
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
system( "whoami" );
setuid( 0 );
system( "whoami" );
return 0;
}
From what I understood it has to be the last line in order to take precedence. Or place it in /etc/sudoers.d in a separate file.You can setup sudo to work without password for certain commands even if they are written in bash. I prefer that over setuid.
## In sudoers, edited with visudo
myuser ALL = (ALL) NOPASSWD: /usr/local/bin/mysudocommand
Yeah I was about to ask whether you could define a Cmnd_Alias for a shell script in sudoers to then add a NOPASSWD exception; but this approach seems to be even simpler. Does it have to come at the end of the sudoers file though?
... sorry about the off-topic spam, though.
You can setup sudo to work without password for certain commands even if they are written in bash. I prefer that over setuid.
## In sudoers, edited with visudo
myuser ALL = (ALL) NOPASSWD: /usr/local/bin/mysudocommand
Wow, I didn't know that. That's definitely better!
Maybe a stupid question, do i need to replace %command% with the actual binary when running this from steam ?
Seems to not really work at least on xenial. Cant't see anything happening when checking the unit with journalctl. scaling_governor always stays at powersave.No, the %command% bit replaces whatever command/binary is used to start the respective steam game.
Maybe a stupid question, do i need to replace %command% with the actual binary when running this from steam ?
How can i use GameMode on Ubuntu?
The easiest thing to do if you're an Ubuntu user is this - Go to the terminal and type:
sudo apt install cpufrequtils indicator-cpufreq
(and enter)
Once installed you'll have a switch on your menu bar which you can set to "Performance" when wanting to run games and "OnDemand" or "PowerSave" when you want to run normal software.
No, the %command% bit replaces whatever command/binary is used to start the respective steam game.
Well then is defiantly not working. Thanks for the confirmation.
does it helps nvidia cards as well?
It affects CPU, not GPU. In general it can help some games with different cards.
Last edited by Shmerl on 11 April 2018 at 7:14 pm UTC
See more from me