1
0
mirror of https://github.com/systemd/systemd synced 2024-07-09 04:26:06 +00:00

user: delegate cpu controller, assign weights to user slices

So far we didn't enable the cpu controller because of overhead of the
accounting. If I'm reading things correctly, delegation was enabled for a while
for the units with user and pam context set, i.e. for user@.service too.
a931ad47a8 added the explicit Delegate=yes|no
switch, but it was initially set to 'yes'.
acc8059129 disabled delegation for user@.service
with the justication that CPU accounting is expensive, but half a year later
a88c5b8ac4 changed DefaultCPUAccounting=yes for
kernels >=4.15 with the justification that CPU accounting is inexpensive there.

In my (very noncomprehensive) testing, I don't see a measurable overhead if the
cpu controller is enabled for user slices. I tried some repeated compilations,
and there is was no statistical difference, but the noise level was fairly
high. Maybe better benchmarking would reveal a difference.

The goal of this change is very simple: currently all of the user session,
including services like the display server and pipewire are under user@.service.
This means that when e.g. a compilation job is started in the session's
app.slice, the processes in session.slice compete for CPU and can be starved.
In particular, audio starts to stutter, etc. With CPU controller enabled,
I can start start 'ninja -C build -j40' in a tab and this doesn't have any
noticable effect on audio.

I don't think the particular values matter too much: the CPU controller is
work-convserving, and presumably the session slice would never need more than
e.g. one 1 full CPU, i.e. half or a quarter of available CPU resources on even
the smallest of today's machines. app.slice and session.slice are assigned
equal weights, background.slice is assigned a smaller fraction. CPUWeight=100
is the default, but I wrote it explicitly to make it easier for users to see
how the split is done. So effectively this should result in session.slice
getting as much power as it needs.

If if turns out that this does have a noticable overhead, we could make it
opt-in. But I think that the benefit to usability is important enough to enable
it by default. W/o something like this the session is not really usable with
background tasks.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2022-07-02 10:33:49 +02:00 committed by Lennart Poettering
parent d486b26fe3
commit b8df7f8629
5 changed files with 12 additions and 1 deletions

2
TODO
View File

@ -1233,6 +1233,8 @@ Features:
- when reloading configuration, apply new cgroup configuration
- when recursively showing the cgroup hierarchy, optionally also show
the hierarchies of child processes
- add settings for cgroup.max.descendants and cgroup.max.depth,
maybe use them for user@.service
* transient units:
- add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt

View File

@ -10,3 +10,6 @@
[Unit]
Description=User Application Slice
Documentation=man:systemd.special(7)
[Slice]
CPUWeight=100

View File

@ -10,3 +10,6 @@
[Unit]
Description=User Background Tasks Slice
Documentation=man:systemd.special(7)
[Slice]
CPUWeight=30

View File

@ -10,3 +10,6 @@
[Unit]
Description=User Core Session Slice
Documentation=man:systemd.special(7)
[Slice]
CPUWeight=100

View File

@ -21,7 +21,7 @@ Type=notify
ExecStart={{ROOTLIBEXECDIR}}/systemd --user
Slice=user-%i.slice
KillMode=mixed
Delegate=pids memory
Delegate=pids memory cpu
TasksMax=infinity
TimeoutStopSec=120s
KeyringMode=inherit