A high-level quality-of-service interface
Quality-of-service (QoS) mechanisms attempt to prioritize some processes (or network traffic, disk I/O, etc.) over others in order to meet a system's performance goals. This is a difficult topic to handle in the world of Linux, where workloads, hardware, and user expectations vary wildly. Qais Yousef spoke at the 2025 Linux Plumbers Conference, alongside his collaborators John Stultz, Steven Rostedt, and Vincent Guittot, about their plans for introducing a high-level QoS API for Linux in a way that leaves end users in control of its configuration. The talk focused specifically on a QoS mechanism for the scheduler, to prioritize access to CPU resources differently for different kinds of processes. (slides; video)
Historically, the server market has been a big factor in optimizing the performance of the Linux scheduler, Yousef said. That has changed somewhat over time, but at least initially the scheduler was extremely throughput-focused. In recent years, there has been more concern given to interactivity, but there are still a lot of stale assumptions about how to wring the best performance out of a Linux system. POSIX hasn't evolved to cover new developments, applications still often spawn one thread per CPU core as though the system has no other workloads running, and so on.
The current default scheduler in the kernel, EEVDF, has a number of configurable parameters that can be adjusted for the system as a whole or per-process; Yousef thought that the best way to implement a QoS API for Linux was to give the scheduler enough information about processes to set reasonable default values for the existing configuration options. In the past, people have focused on the kernel interface used to communicate with the scheduler, he said, but that isn't the problem that matters. What matters is providing a high-level API for applications that doesn't require detailed knowledge of the scheduler's configuration to use.
iOS (and related platforms such as macOS and watchOS) already have an interface like that. It provides four QoS levels for a program to choose between: "user interactive" (for tasks needed to update a program's user interface), "user initiated" (for things that the user is actively doing), "utility" (for tasks that should happen promptly but that don't directly impact the user), and "background" (for tasks that have no particular latency requirements). The QoS level can be set independently per thread in a program.
Yousef proposed stealing that design for use on Linux, and mapping each of those classes to the time slice, policy, ramp-up multiplier, and uclamp settings of the scheduler. Threads would default to the utility class, which would match the scheduler's current default values. Threads in the user interactive or user initiated classes would be given shorter time slices, which tell the scheduler to prioritize latency over throughput. Threads in the background class would be given longer time slices, so that they can run for longer periods without interruption when the system is idle, but would be interrupted if a higher-priority thread became runnable.
One audience member objected that Linux does already have a way to control how
much time is given to different threads: the
deadline scheduler.
Rostedt piped up to ask whether they "really want to run Chrome under the
deadline scheduler?
" He clarified that using the deadline scheduler required
root privileges, but Yousef's proposal was all about allowing normal,
unprivileged applications to provide performance hints. This led to an extended
argument in the audience about deadline scheduling versus performance hinting
until Yousef pulled things back on topic.
Adopting QoS classes in the scheduler would require some changes to the code that handles placing tasks on different CPUs, as well, he said. Right now, the kernel decides which CPU should run a task based on one of four criteria: CPU load, CPU load and energy usage, CPU load and NUMA domain, or core affinity. That should really be extended to consider aspects of the task being placed, Guittot explained. When the load balancer is placing a task with a short time slice, it should first consider idle CPUs (where the task could run right away), but if there are none, it should prefer putting the task on a CPU working on something with a long time slice (so that it can be preempted).
The required code changes in the kernel aren't the main problem, though, Yousef
claimed. The problem is how to encourage application developers to adopt a new API; it
can take years for people to actually use new kernel APIs. "I think we can do
better
", he said. Rather than using an interface based on calling functions
in code, which requires application developers to update their programs to take
them into account, why not use a configuration-file-based approach? That way
applications can ship default configuration files if they care to, but users and
distribution maintainers can add configuration files for any applications they
want to see support the new API. It also leaves the user of the system in
ultimate control: if the application ships an obnoxious default configuration,
they can override it.
One person asked why an application developer wouldn't just ship a configuration setting all of their threads to the highest priority. Another audience member pointed out that the proposed QoS API was really most useful for prioritizing threads within an individual application; a video game would want to make the user interface part of the user interactive class, but giving a background cleanup task the same class would just cause jitter or lag, while slowing down the throughput of background processing.
Yousef also said that the kernel should not be bound to blindly follow an application's configuration no matter what. There should be appropriate access control. If an application requests the user interactive QoS class, but the system knows that the application isn't currently in the foreground (possibly due to hints from the desktop environment, through the use of control groups, or from some other process-management mechanism), it could restrict the application to the utility class instead. On the other hand, any application should probably be allowed to mark a thread as part of the background class in order to get the throughput benefits, since those threads won't impact latency.
The important thing is to give the scheduler more information with which to make reasonable decisions for different workloads, Yousef summarized. For servers, which mostly care about throughput, it makes sense to just leave everything at the default QoS level and let the existing code (which has been mostly optimized for servers already) handle it. For laptops, phones, and other applications where latency is more important than raw throughput, having the few threads that matter most indicated to the scheduler lets it make better decisions.
There is other ongoing work in the kernel that will also help with this, he added. There was a discussion at the conference in the toolchains track (video) about how to enable high-priority tasks to "donate" CPU time (or potentially other resources, such as QoS class or other scheduler settings) to lower-priority tasks that are currently holding a lock that the high-priority task needs. That way, a high-priority task isn't stuck waiting for a low-priority task to be scheduled on the CPU so it can make progress (a situation known as priority inversion). Such work has historically been called priority inheritance, but in the toolchains track talk it was called performance inheritance, to indicate that it can involve more than just priority. Regardless of what it is called, Yousef said that work would also contribute to improving user-visible latency.
Whether Linux will end up adopting a QoS API, and whether it will mimic Apple's API so closely, remains to be seen. It seems clear that there has been a shift in recent years, putting increased focus on concerns other than throughput in the kernel's scheduling subsystem. If that push continues, which seems likely, users may look forward to more responsive user interfaces in the future.
[ Thanks to the Linux Foundation for sponsoring my travel to the Linux Plumbers Conference. ]
