Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

realtime: request SCHED_RR using CAP_SYS_NICE #6994

Merged
merged 1 commit into from
May 18, 2022

Conversation

Emantor
Copy link
Contributor

@Emantor Emantor commented May 14, 2022

Try to gain SCHED_RR (round-robin) realtime scheduling privileges before
starting the server. This requires CAP_SYS_NICE on Linux systems.
We additionally register a pthread_atfork callback which resets the
scheduling class back to SCHED_OTHER (the Linux system default).

Due to CAP_SYS_NICE, setting RLIMIT_RTPRIO has no effect on the process
as documented within man 7 sched (from Linux):

  Privileged (CAP_SYS_NICE) threads ignore the RLIMIT_RTPRIO limit;
  as with older kernels, they can make arbitrary changes to
  scheduling policy and priority. See getrlimit(2) for further
  information on RLIMIT_RTPRIO

Note that this requires the sway distribution packagers to set the
CAP_SYS_NICE capability on the sway binary.

Supersedes #6992

@Emantor Emantor force-pushed the topic/realtime_pthread branch 3 times, most recently from 10cee09 to 06d4ecf Compare May 14, 2022 16:09
@kennylevinsen
Copy link
Member

Hmm. So on FreeBSD, this requires PRIV_SCHED_SET.

From what I can tell that is primarily given to root, but from reading the code it seems like mac(9) can interfere with these decisions. Maybe it can be used to grant the privilege? Might need a FreeBSD expert to comment...

@Emantor
Copy link
Contributor Author

Emantor commented May 15, 2022

Apparently this can be done using mac(9), but requires it's own kernel module (code).

@kennylevinsen
Copy link
Member

... oh. rtkit isn't a thing on FreeBSD either from what I can tell, so maybe this is just not something people do over there. We fail gracefully here anyhow.

(As an aside, I recently noticed that rtkit advices one to try sched_setscheduler before rtkit, so we need the manual sched_setscheduler code anyhow.)

}

void gain_realtime(void) {
int prio = sched_get_priority_min(SCHED_RR);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, so pipewire ends up having priority 9, but sched_get_priority_min(SCHED_RR) is -2 so we're below pipewire which is a little annoying. I wonder where the pipewire's priority comes from - rtkit seems to ask for priority 0?

Copy link
Contributor Author

@Emantor Emantor May 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pipewire uses the MaxRealtimePriorityproperty from RTKit to request the highest possible priority from RTKit. This sounds fine and also sway requesting the lowest sounds good. According to man 2 sched_get_priority_min:

Processes with numerically higher priority values are scheduled before processes with numerically lower priority values.
Thus, the value returned by sched_get_priority_max() will be greater than the value returned by sched_get_priority_min().

So pipewire should be scheduled before sway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pipewire uses the MaxRealtimePriority property from RTKit to request the highest possible priority from RTKit.

Oh, I just realized that I was checking prio, not rtprio. That explains why I was seeing weird numbers. D'oh.

So pipewire should be scheduled before sway.

Yeah, my thought was that it makes sense that we as the graphical window system would have either same or higher priority than audio and screen capture routing. It does seem a bit aggressive from pipewire's perspective to ask for the highest priority, outranking even a bunch of kernel threads...

(This is of course nowhere near as important as just being SCHED_RR in the first place - even if our priority is wrong, we're competing with a much smaller group of processes.)

sway/main.c Outdated Show resolved Hide resolved
@Emantor Emantor force-pushed the topic/realtime_pthread branch 2 times, most recently from df09e47 to 2b72f84 Compare May 16, 2022 12:22
Try to gain SCHED_RR (round-robin) realtime scheduling privileges before
starting the server. This requires CAP_SYS_NICE on Linux systems.
We additionally register a pthread_atfork callback which resets the
scheduling class back to SCHED_OTHER (the Linux system default).

Due to CAP_SYS_NICE, setting RLIMIT_RTPRIO has no effect on the process
as documented within man 7 sched (from Linux):

  Privileged (CAP_SYS_NICE) threads ignore the RLIMIT_RTPRIO limit;
  as with older kernels, they can make arbitrary changes to
  scheduling policy and priority. See getrlimit(2) for further
  information on RLIMIT_RTPRIO

Note that this requires the sway distribution packagers to set the
CAP_SYS_NICE capability on the sway binary.

Supersedes swaywm#6992
@kennylevinsen
Copy link
Member

Other than being unsure about the priority we should use, LGTM.

@Emantor
Copy link
Contributor Author

Emantor commented May 17, 2022

IMO, starting with the minimum priority is fine. We can still adjust this or expose this as a user configurable option later.

@kennylevinsen kennylevinsen merged commit a3a82ef into swaywm:master May 18, 2022
@kennylevinsen
Copy link
Member

Thanks!

@Emantor Emantor deleted the topic/realtime_pthread branch May 18, 2022 10:05
primeos added a commit to primeos/nixpkgs that referenced this pull request Dec 26, 2022
The capability `CAP_SYS_NICE` can be set since Sway 1.8 to improve
scheduling: swaywm/sway#6994

This is optional but we decided to enable it by default as it is useful.
It has some security implications though (but the capabilities are only
for the Sway process itself since we don't make them inheritable).
The definition of `CAP_SYS_NICE` from capabilities(7):
```
* Lower the process nice value (nice(2), setpriority(2)) and change the
  nice value for arbitrary processes;
* set real-time scheduling policies for calling process, and set
  scheduling policies and priorities for arbitrary processes
  (sched_setscheduler(2), sched_setparam(2), sched_setattr(2));
* set CPU affinity for arbitrary processes (sched_setaffinity(2));
* set I/O scheduling class and priority for arbitrary processes
  (ioprio_set(2));
* apply migrate_pages(2) to arbitrary processes and allow processes to
  be migrated to arbitrary nodes;
* apply move_pages(2) to arbitrary processes;
* use the MPOL_MF_MOVE_ALL flag with mbind(2) and move_pages(2).
```

This should help avoiding some stuttering as well as the "your
compositor is too slow" warnings from libinput.
archlinux-github pushed a commit to archlinux/svntogit-community that referenced this pull request Feb 1, 2023
Support for sway to set SCHED_RR was added to improve desktop
responsiveness/stuttering [1]. Upstream advises setting the capability on the
binary [2].

Fixes FS#77225

[1] swaywm/sway#6994
[2] swaywm/sway#6992 (review)


git-svn-id: file:///srv/repos/svn-community/svn@1391627 9fca08f4-af9d-4005-b8df-a31f2cc04f65
archlinux-github pushed a commit to archlinux/svntogit-community that referenced this pull request Feb 1, 2023
Support for sway to set SCHED_RR was added to improve desktop
responsiveness/stuttering [1]. Upstream advises setting the capability on the
binary [2].

Fixes FS#77225

[1] swaywm/sway#6994
[2] swaywm/sway#6992 (review)

git-svn-id: file:///srv/repos/svn-community/svn@1391627 9fca08f4-af9d-4005-b8df-a31f2cc04f65
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants