Christian Schaller wrote an excellent blog post highlighting a lot of the cool new features and improvements that ship with Fedora 31. I wanted to add to that and give an overview of new things and improvements we did for GameMode that will be in Fedora 31. First of all a quick refresher about GameMode:
GameMode is a solution to optimize performance of a GNU/Linux system for gaming. This is to improve frames-per-seconds as well as make games run smoother, i.e. avoid stuttering. Performance optimization is done by applying various global and per-game tweaks: setting the CPU governor, adjusting the I/O priority, changing the niceness of the game and setting a different kernel scheduler (
SCHED_ISO). It recently gained support for setting GPU performance modes (NVIDIA and AMD) and GPU overclocking (NVIDIA). Additionally it will inhibit the screensaver and can execute custom scripts on start and end.
There were two main issues that I focused on: First it was hard to tell if GameMode was currently active and what games/programs were requesting it. The second one was to make GameMode compatible with flatpaks. Both required changes to the GameMode daemon and the API. Upstream was very quick to review and merge all the required patches and roll a release (1.4), thanks a bunch of that.
Visibility and Integration
The whole point of GameMode is to increase the performance of the system in order to have a better gaming experience. This will (almost certainty) come with increased power draw, which is not great for computers attached to the mains but can be very annoying when running on battery. In any way it would be great to have a better idea if GameMode is currently active or not. In Fedora 30 and below this was very hard without dropping to the command line and running something like
systemctl status --user gamemoded. Two improvements should make the situation better:
The first one is a smallish Shell extension (source) that will indicate via a status icon if GameMode is currently active or not. Additionally it will display notifications every time the GameMode status changes (this can be disabled). We needed to additional D-Bus API to the daemon for this, most notably a
ClientCount property (PR#129) that the extension is watching and reacting to, so it needs GameMode 1.4 to work properly.
GameMode Shell Extension - displays a notification and shows a status icon.
The other improvement to visibility, that turned out to be a bit more tricky, is indicating in Usage which process is requesting GameMode. This needed another set of additional D-Bus API endpoints (PR#155, PR#161) to expose all the currently active GameMode clients on the bus. With this, the initial support in Usage was quite straight forward (PR#60) and was basically done by maintaining a list of active GameMode clients and then matching those to Usage process entries.
Usage showing a little game icon for active clients
But it turns out that Usage didn't support flatpaks properly and one of the main ways to play games is Steam, which is best used as a flatpak. After quite a bit of internal refactoring that is now also done (PR#63). Speaking of flatpak, this was the other big area that I worked on:
Games (or in general clients) are requesting GameMode via a simple D-Bus call
RegisterGame(int pid) which as the sole argument has the process identifier (pid) of the process, where it naturally is expected to pass its own pid. Processes can easily discover their own pid via
getpid(2). The GameMode client library that games can use for easy integration with GameMode will do exactly that, i.e. effectively calling
RegisterGame(getpid()). Flatpak, being Linux application sandboxing and distribution framework, uses a pid namespaces to isolate the process ids in the flatpak from the host. That means that a process will effectively have (at least) two process ids. The one inside the flatpak and the one outside, on the host; and it itself can only see the process id inside the flatpak. That is the whole idea about isolation and sandboxing. Now if the game requests gamemode to be activated via
getpid() will give it the process id from the container and the GameMode daemon will be totally confused because the same number on the host will probably not exist or refer to a different process (probably owned by a different user). This prevented e.g. the Steam flatpak to ship with GameMode support (#77).
To solve this issue, we created a new flatpak portal. Instead of talking to GameMode directly, games inside a flatpak should talk to the flatpak portal and the portal will translate the process id from the one inside the flatpak container to the one on the host. The actual translation part was actually not straight forward and deserves a future blog post, but for the curious reader I recommend reading the discussion on the pull-request (#314). We patched the upstream GameMode client library to automatically detect that it is inside a flatpak and transparently use the portal (PR #146) and the daemon to find the executable for programs inside the flatpak (PR#136).
Small application to test GameMode
While working on the flatpak integration I needed something to quickly test various aspects of the integration, the client libs and the GameMode API all inside and outside of a flatpak. For this I created a small application, GameMode Tester, which someone besides me might find useful.
Fedora started shipping GameMode with version 28, with version 30 it is included in the workstation standard install. Fedora 31 will ship with all the necessary bits and pieces: GameMode version 1.4, the Shell extension has been packaged (
dnf install gnome-shell-extension-gamemode) and a Usage with GameMode integration. Happy gaming, everyone!