User:AbhinavPraveen/Optimizing Wine and Proton on Gentoo

From Gentoo Wiki
Jump to:navigation Jump to:search
This article is a stub. Please help out by expanding it - how to get started.

This guide lists some optimizations to Wine and Proton and how to apply them on Gentoo.


If your user is called foo. Then simply append the following to /etc/security/limits.conf:

FILE /etc/security/limits.confEnabling Esync support.
foo hard nofile 524288

Then log out of your user account and log in again. Esync will then be enabled by default in Proton and, if an Esync capable Wine is selected, Esync can be toggled in Lutris. You may also be able to enable it by setting:


as an environment variable. Depending on the implementation, you may also see "esync: up and running." in the logs when enabled and used.


Fsync is an optimization that requires either an experimental kernel patch to work or a 5.16+ kernel. Note that Proton 6.3 and later only support Fsync with kernels 5.13 onwards. While proton 5.13 and earlier should support Fsync with older kernels.

To use the experimental patch for Fsync support, first read /etc/portage/patches. After this, one can easily acquire a good selection of patches by cloning Frogging-Family/linux-tkg and finding the patchset closest to their kernel version. If, for example, you are running kernel 5.10.27, you should navigate to linux-tkg/linux-tkg-patches/5.10 and move your selected patches to /etc/portage/patches/sys-kernel/gentoo-sources-5.10.27:5.10.27. The patches listed below are used by the author.

user $cd linux-tkg/linux-tkg-patches/5.10
user $ls
root #mkdir -p /etc/portage/patches/sys-kernel/gentoo-sources-5.10.27:5.10.27
root #cp 0002-clear-patches.patch 0007-v5.10-fsync.patch 0007-v5.10-futex2_interface.patch /etc/portage/patches/sys-kernel/gentoo-sources-5.10.27:5.10.27
root #cd /usr/src/linux
root #make clean
root #emerge --ask --oneshot =gentoo-sources-5.10.27:5.10.27

Note that any revision number must be included e.g: gentoo-sources-5.10.76-r1:5.10.76-r1 Then, making sure that the kernel is eselected, enable CONFIG_FUTEX2 using your chosen menuconfig tool under /usr/src/linux and build the kernel. See Kernel/Configuration for more information. After booting into the new kernel, one can check dmesg if the option is enabled as follows:

user $dmesg | grep futex
[    0.122723] futex hash table entries: 4096 (order: 6, 262144 bytes, linear)
[    0.122723] futex2 hash table entries: 4096 (order: 4, 98304 bytes, linear)

Following this, Proton will enable Fsync/Futex2 by default, the option can be toggled in Lutris when using a compatible Wine version and can be enabled by setting the environment variable:


Depending on the implementation, you may also see "futex2: up and running." in the logs when enabled and used.


The portage in-tree Wine is not compatible with Esync or Fsync. app-emulation/wine-lutris (recommended) and app-emulation/wine-tkg are available in the 'ap-overlay' overlay; both supporting Esync and Fsync. To use these, add 'ap-overlay' with layman and emerge your chosen package. Otherwise, the steps to creating a 'wine-lutris' ebuild are given below.

First go to and pick a version and copy the link to its source files e.g Lutris Wine 6.21 and later do not support the 'old' futex2 interface available for kernel 5.12 and earlier and only support the interface mainlined in 5.16 with available backports to 5.15, 5.14 and 5.13. Hence, if you wish to use an older kernel and Fsync, pick 6.14-4 or earlier.

The latest version is often fine. Then create a local overlay as described in Custom ebuild repository named, for example, localrepo. Copy the portage in-tree wine-vanilla ebuilds to the overlay and replace the source files with the Lutris source. Note that this will typically not be a wine-vanilla build however, if we were to copy to the wine-staging ebuild, portage would attempt to apply the staging patches a second time on top of our Lutris source which (typically) already has these applied. While this may not be the ideal way to do this, it is quick and easy.

root #mkdir -p /var/db/repos/localrepo/app-emulation
root #cp -r /var/db/repos/gentoo/app-emulation/wine-vanilla /var/db/repos/localrepo/app-emulation/
root #ls /var/db/repos/localrepo/app-emulation/wine-vanilla
Manifest      wine-vanilla-6.0.2.ebuild  wine-vanilla-6.19.ebuild  wine-vanilla-6.21.ebuild
metadata.xml  wine-vanilla-6.14.ebuild	 wine-vanilla-6.20.ebuild  wine-vanilla-9999.ebuild

Find the existing in-tree wine ebuild that is closest to the Lutris wine version you have chosen. If they have the same major version, in this case it would be 6.21, skip the following step. If not, create it from a similar ebuild. If, for example, our chosen Lutris major version (6.21) does not have an ebuild but a nearby version (6.22) does, create a copy and change the wine-mono version in the ebuild as according to (or install it manually). For example, Lutris Wine 6.14 would require Mono 6.3.0.

root #cp /var/db/repos/localrepo/app-emulation/wine-vanilla/wine-vanilla-6.22.ebuild cp /var/db/repos/localrepo/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild

Then open the selected ebuild in a text editor. Then find the following line:


and replace it with the URL for the Lutris/Wine source e.g


Then in the ebuild's src_unpack, after:



mv "${WORKDIR}"/wine-lutris-6.21-5 "${WORKDIR}"/wine-6.21

Replacing 6.21-5 with your chosen Lutris Wine verion and 6.21 with with the major version (i.e excluding -5 from 6.21-5). Then comparing the original ebuild and the new one, you should see something resembling:

user $diff -u /var/db/repos/{gentoo,localrepo}/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild
--- /var/db/repos/gentoo/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild	2021-11-06 22:09:39.000000000 +0000
+++ /var/db/repos/localrepo/app-emulation/wine-vanilla/wine-vanilla-6.21.ebuild	2021-11-27 19:15:09.689676215 +0000
@@ -19,7 +19,7 @@
 	MAJOR_V=$(ver_cut 1)
-	SRC_URI="${MAJOR_V}.x/${MY_P}.tar.xz"
+	SRC_URI=""
 	KEYWORDS="-* ~amd64 ~x86"
@@ -304,6 +304,7 @@

+	mv "${WORKDIR}"/wine-lutris-6.21-5 "${WORKDIR}"/wine-6.21

 	plocale_find_changes "${S}/po" "" ".po"

Then use repoman to create the Manifest and build the package as usual.

root #emerge --ask --verbose app-portage/repoman
root #cd /var/db/repos/localrepo/app-emulation/wine-vanilla
root #repoman manifest
root #emerge --ask --verbose =wine-vanilla-6.21::localrepo

Finally, select the wine version with eselect wine if desired. You should then see:

user $/usr/bin/wine-vanilla-6.21
wine-6.21.r0.g63c3baa9 ( TkG Staging Esync Fsync )

You can then select this version in Lutris.

Realtime Scheduling

By running the game as a 'realtime' proces, you can tell the scheduler to, up to a specified fraction of cpu-time (95% by default), always run tasks from the game before any other task. Note that this a bit of a hack and will not help in all circumstances. For example, if the game takes up so much CPU time that the GPU drivers cannot run, then you will not get any frames. By default, only root can assign realtime scheduling. We will use setcap (from sys-libs/libcap) on a copy of /usr/bin/chrt to allow foo to do this. A similar approach can be used to set niceness instead. Again, assuming that your username is foo:

root #mkdir /home/foo/.bin
root #chmod 0500 /home/foo/.bin
root #chown foo /home/foo/.bin
root #cp /usr/bin/chrt /home/foo/.bin
root #chmod 0000 /home/foo/.bin/chrt
root #setfacl -m 'u:foo:rx' /home/foo/.bin/chrt
root #setcap cap_sys_nice+ep /home/foo/.bin/chrt

Note that anyone that can misuse /home/foo/.bin/chrt can cause denial of service. Then you can use the following as a command prefix in Lutris.

/home/foo/.bin/chrt --rr 5

Or the following as a launch option in steam.

/home/foo/.bin/chrt --rr 5 %command%

The author also recommends adding the following, allowing the game to use 99% of CPU time:

FILE /etc/sysctl.confChanging CPU time limit.

And setting the following in the kernel command line.