Linux 5.16 took a week longer than originally expected. Linus Torvalds decided to give the kernel a little more time to mature. The triggers were not problems or alarming test results, but simply the concern that testing could be too short due to the holidays and the week “between the years”.
In fact, in the extra week with rc8, no major changes came to the table. The new kernel saw the light of day on Monday night and was more likely to be expected as a maintenance release. Nevertheless, 5.16 offers some interesting new features such as entry into futex2, active alerting of file system errors at kernel level, a “cluster-aware” CPU scheduler and increased security. The new kernel also tackles a mammoth task with folio pages for efficient and performance-enhancing memory management.
Faster games thanks to futex2
Linux 5.16 gives the go-ahead for futex2 and promises better performance, especially when emulating Windows games. In the long term, futex2 is intended to replace the outdated and historically grown system call futex(). Futex stands for “Fast User Mutex”. It allows mutexes, i.e. locks for competing access, not only to be used in kernel space but also in user space.
The concept was introduced back in 2003 in kernel 2.6.0 in the form of the futex() system call. The first central application was the system call for controlling the concurrency of POSIX threads. Previously, userspace processes could only rely on semaphores, for example via eventfd() when accessing shared resources.
Semaphores provide a mechanism to “signal” freed resources. A process or thread waiting for a resource to become free regularly checks whether access is now possible. Mutexes, on the other hand, lock resources until they become free again. A call to futex() blocks the process or thread until the resource in question becomes free. Mutexes are therefore generally leaner to use and more CPU-defensive in the kernel than semaphores.
Historically grown: futex()
Due to the popularity of futex(), the system call is used in many application scenarios. Therefore, calls for a reengineering of the call became louder in order to get application-related individual functions or at least wrappers in the libc. As a reaction, André Almeida’s futex2 approach followed about two years ago with the aim of creating a flexible futex subsystem.
Even in Linux 5.16, futex2 is still a long way from being a replacement for the old futex(). The approach incorporated is a light variant that addresses a specific problem. The previous futex() is limited in its function. It can only query a futex. If several are to be considered, this can only be done one after the other. With the shortcoming of running into multiple blocking calls to futex() in a row. This has disadvantages, especially with ported Windows games that use emulation layers such as WINE or Proton’s Steam Play.
Mimicry of the Windows API
The Windows API provides the Funktion WaitForMultipleObjects(), which allows querying multiple objects. These objects can be used analogously to the resources and futexes in Linux. However, Windows can carry out the query in parallel in one call. Linux not yet. This is where Linux 5.16 with the first futex2 patch on. The kernel introduces the system call futex_waitv(), which – unlike futex() – can wait for multiple mutex or their release. This allows Linux 5.16 to more elegantly and efficiently emulate WaitForMultipleObjects() in emulation layers. Ported games benefit from a speed gain.
André Almeida may see the potentialto also accelerate native Linux games using the new system call: “Native game engines will also benefit, provided this wait pattern is common for games.” A documentation of futex2 and futex_waitv() can be found in the unpacked kernel sources under Documentation/userspace-api/futex2.rst, alternatively also in the relevant patch.