Every article tag can be clicked to get a list of all articles in that category. Every article tag also has an RSS feed! You can customize an RSS feed too!
We do often include affiliate links to earn us some pennies. See more here.

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.

Article taken from GamingOnLinux.com.
59 Likes
About the author -
author picture
I am the owner of GamingOnLinux. After discovering Linux back in the days of Mandrake in 2003, I constantly came back to check on the progress of Linux until Ubuntu appeared on the scene and it helped me to really love it. You can reach me easily by emailing GamingOnLinux directly. Find me on Mastodon.
See more from me
The comments on this article are closed.
92 comments
Page: «9/10»
  Go to:

marcus Apr 12, 2018
View PC info
  • Supporter
Quoting: NeverthelessI 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;
}

No its not :) You are confusing uid and euid (effective user id). Whoami is the wrong command to show what you want to show since it outputs the username based on the UID. But the UID is not what is used to check privileges. (See man credentials for the difference between user id and effective user id.)

Try with this code snippet instead:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main() { 
    printf("EUID: %i\n",geteuid());
    printf("UID: %i\n",getuid());
}


The EUID is what matters when you write to files. Unless you want to use setuid() to change the apparent username to root (and then output it using whoami) it is useless. You can NOT elevate privileges this way.

Hmm ... @Liam: Indentation is somehow broken for code blocks or I'm too stupid ;)


Last edited by marcus on 12 April 2018 at 7:15 am UTC
Nevertheless Apr 12, 2018
Quoting: marcus
Quoting: NeverthelessI 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;
}

No its not :) You are confusing uid and euid (effective user id). Whoami is the wrong command to show what you want to show since it outputs the username based on the UID. But the UID is not what is used to check privileges. (See man credentials for the difference between user id and effective user id.)

Try with this code snippet instead:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main() { 
    printf("EUID: %i\n",geteuid());
    printf("UID: %i\n",getuid());
}


The EUID is what matters when you write to files. Unless you want to use setuid() to change the apparent username to root (and then output it using whoami) it is useless. You can NOT elevate privileges this way.

Hmm ... @Liam: Indentation is somehow broken for code blocks or I'm too stupid ;)

Easier... just try setting the cpu governor without it :)
Don't get me wrong.. what you say makes sense! I don't know really why a suid file owned by root needs this... Maybe it's some security measure, checking if a program is really wanted to be started as suid-root. I don't know! All I know is, that on may system I have add the line to make it work.


Last edited by Nevertheless on 12 April 2018 at 8:50 am UTC
marcus Apr 12, 2018
View PC info
  • Supporter
Quoting: NeverthelessEasier... just try setting the cpu governor without it :)

Interesting ... learned something new ...

(all binaries with setuid-root)

It works without the setuid call:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main() { 
        printf("EUID: %i\n",geteuid());
        printf("UID: %i\n",getuid());
        FILE* file = fopen("/sys/devices/system/cpu/cpu1/online","w");
        if (!file) {
                perror("Error opening: \n");
                return -1;
        }
        if (fprintf(file,"0\n") < 0) {
                perror("Error writing: \n");
                return -2;
        }
}


(Sorry, have no governors to set, so I just used cpu1/online for the same effect).

However, it does not work if you use system (which you should not do to begin with ^^, see also Caveats section in man 3 system and https://stackoverflow.com/questions/27461936/system-vs-execve. This is because the EUID is not propagated to the program called by system, while the UID is.

steam@SteamBox ~ $ cat test2.c
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() { 
        printf("EUID: %i\n",geteuid());
        printf("UID: %i\n",getuid());
        system("echo EUID_System: $EUID");
}
steam@SteamBox ~ $ ./test2 
EUID: 0
UID: 1000
EUID_System: 1000
steam@SteamBox ~ $


steam@SteamBox ~ $ ./test3 
EUID: 0
UID: 0
EUID_System: 0
steam@SteamBox ~ $ cat test3.c 
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() { 
        setuid(0);
        printf("EUID: %i\n",geteuid());
        printf("UID: %i\n",getuid());
        system("echo EUID_System: $EUID");
}
steam@SteamBox ~ $ 


Bottom line: Please don't use system in a setuid-root binary. This is broken and a serious security hole.


Last edited by marcus on 12 April 2018 at 8:53 am UTC
Nevertheless Apr 12, 2018
Quoting: marcus
Quoting: NeverthelessEasier... just try setting the cpu governor without it :)

Interesting ... learned something new ...

(all binaries with setuid-root)

It works without the setuid call:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main() { 
        printf("EUID: %i\n",geteuid());
        printf("UID: %i\n",getuid());
        FILE* file = fopen("/sys/devices/system/cpu/cpu1/online","w");
        if (!file) {
                perror("Error opening: \n");
                return -1;
        }
        if (fprintf(file,"0\n") < 0) {
                perror("Error writing: \n");
                return -2;
        }
}


(Sorry, have no governors to set, so I just used cpu1/online for the same effect).

However, it does not work if you use system (which you should not do to begin with ^^, see also Caveats section in man 3 system and https://stackoverflow.com/questions/27461936/system-vs-execve. This is because the EUID is not propagated to the program called by system, while the UID is.

steam@SteamBox ~ $ cat test2.c
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() { 
        printf("EUID: %i\n",geteuid());
        printf("UID: %i\n",getuid());
        system("echo EUID_System: $EUID");
}
steam@SteamBox ~ $ ./test2 
EUID: 0
UID: 1000
EUID_System: 1000
steam@SteamBox ~ $


steam@SteamBox ~ $ ./test3 
EUID: 0
UID: 0
EUID_System: 0
steam@SteamBox ~ $ cat test3.c 
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() { 
        setuid(0);
        printf("EUID: %i\n",geteuid());
        printf("UID: %i\n",getuid());
        system("echo EUID_System: $EUID");
}
steam@SteamBox ~ $ 


Bottom line: Please don't use system in a setuid-root binary. This is broken and a serious security hole.

This was not a serious solution for a problem, it was just a hack, a thought if you like. Of course it doesn't even make much sense to have "system" call echo to write into a file, when you can do it with c itself. I still don't see a big security risk in this special case, but with the possibility to replace "system", or better use sudo for the same effect, we can now just completely forget about the idea anyway.
seven Apr 14, 2018
could somebody plz make a .deb or .sh file from that so its easier to install
Eike Apr 14, 2018
View PC info
  • Supporter Plus
Quoting: sevencould somebody plz make a .deb or .sh file from that so its easier to install

I wondered if I should make the Debian package, but the Debian games team is already working on it:
https://salsa.debian.org/games-team/gamemode
Jahimself Apr 14, 2018
QuoteThat's not correct. Feral themselves claimed that Windows thread scheduler is way smarter when it comes to games.

Except that windows game mode managed to decrease performance...
strunkenbold Apr 15, 2018
Quoting: Jahimself
QuoteThat's not correct. Feral themselves claimed that Windows thread scheduler is way smarter when it comes to games.

Except that windows game mode managed to decrease performance...

Except that you making it sound like Windows Game Mode will always decrease performance. Which isnt the case. On high end desktops with a large amount of CPU threads available, Game Mode wont help much if at all. But it does very well on low end and high background tasks load.

Its like comparing apples to oranges anyway, as Ferals Game Mode changes the CPU scheduler to performance which makes the CPU stop from up -and downclocking, whereas Windows Game Mode just shifts priorities from normal to low for any background task and high or realtime for the game itself.

If you see how much CoH2 improves, despite its actually running at low FPS, its actually clear that something like Ferals tool is long overdue and desperately needed.
The sad conclusion is that Linux doesnt offer optimal performance out of the box and you need to start messing around with steam launch options or prefixes which isnt really beginners friendly.
NOX LinuX Apr 15, 2018
I paste this Command on Steam launch option on XCOM 2 Game and I get approximately 4 FPS+,nice job Feral Interactive keep it up!!!:)

LD_PRELOAD=$LD_PRELOAD:/usr/\$LIB/libgamemodeauto.so %command%


Last edited by NOX LinuX on 15 April 2018 at 1:48 pm UTC
Jahimself Apr 19, 2018
QuoteOn high end desktops with a large amount of CPU threads available, Game Mode wont help much if at all.

Well loosing 10% perf is not what is expected for a game mode especially on high end desktop. All the DX12 possible gain can only happen on modern hardware supporting the API anyway. So game mode will more concern people owning a HP or ACER small budget tower filled up with bloatware than is almost unusable straight after purchase, and even in that case gamemode of microsoft won't do much.

The problem of windows 10, is that you have to close way more process than previous windows version, as you have all the apps running in the background and that you can't uninstall it definitly whatever tricks you use. Windows 10 has way more stuff to do manually to get your game optimised than linux has nowadays IMO.

I agree with the technical aspect of your argumentation towards CPU scheduler. And as you said it's a small tool but it works as intended and has good results.
While you're here, please consider supporting GamingOnLinux on:

Reward Tiers: Patreon. Plain Donations: PayPal.

This ensures all of our main content remains totally free for everyone! Patreon supporters can also remove all adverts and sponsors! Supporting us helps bring good, fresh content. Without your continued support, we simply could not continue!

You can find even more ways to support us on this dedicated page any time. If you already are, thank you!
The comments on this article are closed.