Re: [PATCH v2 RFC 08/13] sched/qos: Add a new sched-qos interface

From: Qais Yousef

Date: Tue May 19 2026 - 07:12:14 EST


On 05/19/26 11:47, Peter Zijlstra wrote:
> On Mon, May 04, 2026 at 02:59:58AM +0100, Qais Yousef wrote:
>
> > QoS is treated as a scarce resource and the intention is for the
> > a syscall to be done for each individual QoS tag. QoS tags are not
> > inherited on fork by default too for the same reason.
>
> This is somewhat awkward. Most all state is inherited on fork. And all
> our tools are built around that. This is for example how I set a shorter
> slice on proton when launching a game (chrt -o --sched-runtime 280000
> 0). Tagging each individual thread that comes out of wine / random .exe
> is going to be painful.

Hmm. The problem is that with the benefit of a hindsight and after running
different experiments, you really don't want to inherit these properties by
default. I think if this tagging is not all designed, you end up with randoms.

With schedqos it is easy to tag all tasks by the way.

For example

{
"chrome": {
"qos": "QOS_INTERACTIVE"
}
}

will cause all chrome tasks to be interactive by default, from /var/log/schedqos.log

[2026-05-19 11:24:36] [INFO] [qos_manager.c:262] New app instance of 505409 /snap/chromium/3258/usr/lib/chromium-browser/chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505409:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505410:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505410 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505411:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505411 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505412:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505412 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505413:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505413 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505410:505409 PerfettoTrace
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505410 PerfettoTrace
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505412:505409 ThreadPoolForeg
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505412 ThreadPoolForeg
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505414:505409 ThreadPoolForeg
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505414 ThreadPoolForeg
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505413:505409 Chrome_ChildIOT
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505413 Chrome_ChildIOT
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505411:505409 ThreadPoolServi
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505411 ThreadPoolServi
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505414:505409 ThreadPoolForeg
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505414 ThreadPoolForeg
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505415:505409 Compositor
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505415 Compositor
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505415:505409 Compositor
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505415 Compositor
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505416:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505416 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505416:505409 ThreadPoolSingl
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505416 ThreadPoolSingl
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505417:505409 chrome
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505417 chrome
[2026-05-19 11:24:36] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505417:505409 HangWatcher
[2026-05-19 11:24:36] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505417 HangWatcher

This is what I call the poor/easy way to tag; but the log gives you all created
tasks so you can try to use that to create smarter tagging, I found by
experiment for instance that the main chrome thread is the main interactive
task and while speedometer still drops a little bit, but I get really close
with this simple intentional tagging

{
"chrome": {
"thread_qos": {
"chrome": "QOS_INTERACTIVE"
}
}
}

sudo schedqos restart --daemon
(no need to reboot or even restart chrome)

[2026-05-19 11:28:38] [INFO] [qos_manager.c:262] New app instance of 505345 /snap/chromium/3258/usr/lib/chromium-browser/chrome
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505345:505345 chrome
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505345 chrome
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505346:505345 PerfettoTrace
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505346 PerfettoTrace
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505348:505345 ThreadPoolServi
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505348 ThreadPoolServi
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505349:505345 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505349 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505350:505345 Chrome_ChildIOT
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505350 Chrome_ChildIOT
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505351:505345 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505351 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505363:505345 Compositor
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505363 Compositor
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505367:505345 ThreadPoolSingl
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505367 ThreadPoolSingl
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505368:505345 HangWatcher
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505368 HangWatcher
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505407:505345 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505407 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505766:505345 MemoryInfra
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505766 MemoryInfra
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505405:505405 kworker/u4:4-ev
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505405 kworker/u4:4-ev
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505406:505406 kworker/u4:5
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505406 kworker/u4:5
[2026-05-19 11:28:38] [INFO] [qos_manager.c:262] New app instance of 505409 /snap/chromium/3258/usr/lib/chromium-browser/chrome
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_USER_INTERACTIVE for 505409:505409 chrome
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_USER_INTERACTIVE for 505409 chrome
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505410:505409 PerfettoTrace
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505410 PerfettoTrace
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505411:505409 ThreadPoolServi
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505411 ThreadPoolServi
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505412:505409 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505412 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505413:505409 Chrome_ChildIOT
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505413 Chrome_ChildIOT
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505414:505409 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505414 ThreadPoolForeg
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505415:505409 Compositor
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505415 Compositor
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505416:505409 ThreadPoolSingl
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505416 ThreadPoolSingl
[2026-05-19 11:28:38] [INFO] [qos_manager.c:309] Applying QoS Tag QOS_DEFAULT for 505417:505409 HangWatcher
[2026-05-19 11:28:38] [INFO] [qos_tagging.c:271] Applying QoS Tag QOS_DEFAULT for 505417 HangWatcher

You should be able to use that for testing by the way already instead of chrt
:-)

Actually on my laptop since I am very power sensitive and I use chrome a lot
I have this config to force all chrome tasks to be background except for one
(uclamp_max should help prevent using the top freqs often when not needed to
deliver meaningful perf)

{
"chrome": {
"qos": "QOS_BACKGROUND",
"thread_qos": {
"chrome": "QOS_INTERACTIVE"
}
}
}


I did create a config for steam to test gaming, but I still can't get a booting
kernel on ToT for my M1 system to run tests and collect more data.. The other
machine I have is poor for gaming workloads.

You can control the slice values for each QoS levels from qos_mappings.json.
Restarting the daemon is enough for it to take effect globally. So you can
change configs, restart and collect data for different experiments on the fly.

Only caveat: you have to reboot to undo schedqos fiddling with all tasks.
I don't have a good way to restore system state yet and I am not sure it can be
reversible..

>
> Can't we have both by using something like SCHED_FLAG_RESET_ON_FORK
> combined with setting a hint?

We had similar discussion in the past in [1]. And I think we'll end up getting
more of such proposals to selectively reset specific tags.

I do set this flag anyway in schedqos so that we can introduce the option to
introduce new high level QoS to take advantage of RT, DL etc. Not that users
can escape schedqos listening to all forks and execs anyway :p

Anyway, my point is that I hopefully fixed the problem how folks can be
intentional very easily, and while I won't spend a lot of time arguing for it,
but my strong recommendation being reserved and not inherit is the easier
problem to deal with. A big part of the problem space is noise management, not
just functional development of new QoS.

We still have the question whether we must enforce a single CAP_PERF_MANAGER
user of this interface. Maybe at LPC we can discuss these details better.

[1] https://lore.kernel.org/lkml/20230416213406.2966521-1-davidai@xxxxxxxxxx/