Coder Social home page Coder Social logo

pop-os / system76-scheduler Goto Github PK

View Code? Open in Web Editor NEW
483.0 22.0 32.0 180 KB

Auto-configure CFS and process priorities for improved desktop responsiveness

License: Mozilla Public License 2.0

Rust 95.59% Just 2.46% Nix 1.95%
linux process priority zen cfs scheduler

system76-scheduler's Introduction

System76 Scheduler

Scheduling service which optimizes Linux's CPU scheduler and automatically assigns process priorities for improved desktop responsiveness. Low latency CPU scheduling will be activated automatically when on AC, and the default scheduling latencies set on battery. Processes are regularly sweeped and assigned process priorities based on configuration files. When combined with pop-shell, foreground processes and their sub-processes will be given higher process priority.

These changes result in a noticeable improvement in the experienced smoothness and performance of applications and games. The improved responsiveness of applications is most noticeable on older systems with budget hardware, whereas games will benefit from higher framerates and reduced jitter. This is because background applications and services will be given a smaller portion of leftover CPU budget after the active process has had the most time on the CPU.

Install

Requires dependencies as defined in the debian/control file:

  • cargo & rustc
  • clang
  • just
  • libclang-dev
  • libpipewire-0.3-dev
  • pkg-config

Then the included justfile can be used to build and install:

just execsnoop=$(which execsnoop-bpfcc) build-release
sudo just sysconfdir=/usr/share install

DBus

  • Interface: com.system76.Scheduler
  • Path: /com/system76/Scheduler

The SetForeground(u32) method can be called to change the active foreground process.

Scheduler Config

The configuration file is stored at the following locations:

  • System: /etc/system76-scheduler/config.kdl
  • Distribution: /usr/share/system76-scheduler/config.kdl

Presence of the system configuration will override the distribution configuration. The documented default configuration can be found here.

Note that if the background and foreground assignment profiles are defined, then foreground process management will be enabled. Likewise, if a pipewire profile is defined, then pipewire process monitoring will be enabled.

Process Priority Assignments

In addition to config.kdl, additional process scheduling profiles are stored in:

  • User-config: /etc/system76-scheduler/process-scheduler/
  • Distribution: /usr/share/system76-scheduler/process-scheduler/

An example configuration is provided here. It is parsed the same as the assignments and exceptions nodes in the main config, and profiles can inherit values from the previous assignment of the same name.

Profile

assignments {
    {{profile-name}} {{profile-properties}}
}

The profile-name can refer to any name of your choice. If the name matches a previous assignment, it will inherit the values from that assignment, plus any additional profile properties assigned.

The profile-properties may contain any of

  • Niceness priority, defined as nice=-20 through nice=19

  • A scheduler policy defined as one of:

    • sched="batch"
    • sched="idle",
    • sched="other"
    • sched=(fifo)1 through sched=(fifo)99
    • sched=(rr)1 through sched=(rr)99

Realtime scheduler policies assign a priority level between 1 and 99. Higher values have higher priority. It is recommended not to set a higher priority than hardware IRQs (>49)

  • An I/O priority defined as one of
    • io="idle"
    • io=(best-effort)0 through io=(best-effort)7
    • io=(realtime)0 through io=(realtime)7

The best-effort and realtime classes have priority levels between 0 and 7, where 7 has the least priority, and 0 is the highest priority

Assignments

Each child element of a profile defines th process(es) to assign to the profile.

{{profile-name}} {{profile-properties}} {
    "/match/by/cmdline" {{profile-properties}}
    match-by-name {{profile-properties}}
    * {{condition-properties}} {{profile-properties}}
}
  • A node name starting with a / is a match by command line path
  • A node name otherwise is a match by process name
  • * matches all processes, used with additional condition-properties
    • properties are wild-match'd
    • properties may start with ! to exclude results matching the condition
    • cgroup="cgroup-path" matches processes by a cgroup
    • parent="name" matches processes by the process name of the parent

CPU Scheduler Latency Configurations

Default

The default settings for CFS by the Linux kernel. Achieves a high level of throughput for CPU-bound tasks at the cost of increased latency for inputs. This setting is ideal for servers and laptops on battery, because low-latency scheduling sacrifices some energy efficiency for improved responsiveness.

latency: 6ns
minimum_granularity: 0.75ms
wakeup_granularity: 1.0ms
bandwidth_size: 5us

Responsive

Slightly reduces time given to CPU-bound tasks to give more time to other processes, particularly those awaiting and responding to user inputs. This can significantly improve desktop responsiveness for a slight penalty in throughput on CPU-bound tasks.

latency: 4ns
minimum_granularity: 0.4ms
wakeup_granularity: 0.5ms
bandwidth_size: 3us

License

Licensed under the Mozilla Public License 2.0. Permissions of this copyleft license are conditioned on making available source code of licensed files and modifications of those files under the same license (or in certain cases, one of the GNU licenses). Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. However, a larger work using the licensed work may be distributed under different terms and without source code for files added in the larger work.

Contribution

Any contribution intentionally submitted for inclusion in the work by you shall be licensed under the Mozilla Public License 2.0 (MPL-2.0). It is required to add a boilerplate copyright notice to the top of each file:

// Copyright {year} {person OR org} <{email}>
// SPDX-License-Identifier: MPL-2.0

system76-scheduler's People

Contributors

cmm avatar jacobgkau avatar kylegospo avatar mmstick avatar parkmycar avatar robobenklein avatar russelltg avatar taoky avatar techsy730 avatar tititiou36 avatar umio-yasuno avatar vrmiguel avatar whynothugo avatar yethal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

system76-scheduler's Issues

DBus socket not accessible by non-root users

Hi! I'm writing a tiny daemon to make this scheduler work with swaywm. That is, when the currently focused window changes, call SetForeground(u32).

Regrettably, it seems that non-root users cannot access the com.system76.Scheduler bus. I used d-feet to try and use it interactively, and get:

org.freedesktop.DBus.Error.AccessDenied: Sender is not authorized to send message (9)

Isn't this method intended to be called by the desktop user? Am I missing something?

High CPU usage + high laptop temps

For the last couple of days, my laptop has seen a huge increase in temperatures, and the cause seems to be the high cpu usage of system76-scheduler, killing it immediately reduces cpu usage dramatically and lowers temperatures

system76-scheduler:
  Installed: 2.0.0~1682509199~22.04~97a8617
  Candidate: 2.0.0~1682509199~22.04~97a8617
  Version table:
 *** 2.0.0~1682509199~22.04~97a8617 1001
       1001 http://apt.pop-os.org/release jammy/main amd64 Packages
        100 /var/lib/dpkg/status

NixOS support

According to my observations the boost-foreground-deboost-background logic takes precedence over the pipewire-client-boost logic, which does not seem terribly useful.

I wonder if there is a way to work around this? I mean I can just disable the fg/bg logic altogether, thankfully, but that's a sledgehammer.

Incompatibility with Secure Boot & Lockdown

On Linux distros with Secure Boot enabled Kernel Lockdown can prevent access to /sys/kernel/debug/*, rendering system76-scheduler unable to tune the scheduler:

May 24 09:59:37 daedalus system76-scheduler[240248]: failed to set value in /sys/kernel/debug/sched/latency_ns: Operation not permitted (os error 1)
May 24 09:59:37 daedalus system76-scheduler[240248]: failed to set value in /sys/kernel/debug/sched/min_granularity_ns: Operation not permitted (os error 1)
May 24 09:59:37 daedalus system76-scheduler[240248]: failed to set value in /sys/kernel/debug/sched/wakeup_granularity_ns: Operation not permitted (os error 1)
May 24 09:59:37 daedalus system76-scheduler[240248]: failed to set value in /sys/kernel/debug/sched/preempt: Operation not permitted (os error 1)

Outside of a kernel patch to add new params outside of debug there may not be a way around this as those params can only be tweaked at boot in this scenario from what I can tell. Might just need to update documentation to warn the user about this.

Specify Release 1.0.0 requires Rust 1.58.0 or later.

The version of Rust given by 'cargo' on current Ubuntu 21.10 is 1.57.0 so the compilation fails. I found that installing via the curl script on their website rust-lang.org gets the most recent version of Rust

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

and this allowed system76-scheduler to compile.

Just wanted to make a note of this for others who come through trying to figure out why it won't compile (the errors do not make this clear). This dependency should probably be noted somewhere officially associated with the 1.0.0 release.

Memory usage

Hey there, I just wanted to report this since I happened to notice it.

Not sure if the schedulers memory usage is because of pipewire, or vice versa?

Error: kernel does not support tweaking the scheduler

When I try to change the profile or start the daemon I get the following error:

$ system76-scheduler daemon
 INFO system76_scheduler: starting daemon service
Error: kernel does not support tweaking the scheduler

I did not try to install a custom kernel or anything like that. This is a fresh install getting regular updates through apt upgrade.

/etc/os-release
NAME="Pop!_OS"
VERSION="22.04 LTS"
ID=pop
ID_LIKE="ubuntu debian"
PRETTY_NAME="Pop!_OS 22.04 LTS"
VERSION_ID="22.04"
HOME_URL="https://pop.system76.com"
SUPPORT_URL="https://support.system76.com"
BUG_REPORT_URL="https://github.com/pop-os/pop/issues"
PRIVACY_POLICY_URL="https://system76.com/privacy"
VERSION_CODENAME=jammy
UBUNTU_CODENAME=jammy
LOGO=distributor-logo-pop-os
/proc/version
Linux version 6.2.6-76060206-generic ([email protected])
(x86_64-linux-gnu-gcc-12 (Ubuntu 12.1.0-2ubuntu1~22.04)
12.1.0, GNU ld (GNU Binutils for Ubuntu) 2.38)
#202303130630~1679424972~22.04~4a8cde1
SMP PREEMPT_DYNAMIC Tue M

I've read in #18 that I need access to /sys/kernel/debug/sched/ but I am not sure how I can enable access. I looks like the files are there and they have values in them.

sudo ls -l /sys/kernel/debug/sched/
total 0
-r--r--r--  1 root root 0 Mar 26 11:09 debug
drwxr-xr-x 18 root root 0 Mar 26 11:09 domains
-rw-r--r--  1 root root 0 Mar 26 11:09 features
-rw-r--r--  1 root root 0 Mar 26 11:09 idle_min_granularity_ns
-rw-r--r--  1 root root 0 Mar 26 11:09 latency_ns
-rw-r--r--  1 root root 0 Mar 26 11:09 latency_warn_ms
-rw-r--r--  1 root root 0 Mar 26 11:09 latency_warn_once
-rw-r--r--  1 root root 0 Mar 26 11:09 migration_cost_ns
-rw-r--r--  1 root root 0 Mar 26 11:09 min_granularity_ns
-rw-r--r--  1 root root 0 Mar 26 11:09 nr_migrate
drwxr-xr-x  2 root root 0 Mar 26 11:09 numa_balancing
-rw-r--r--  1 root root 0 Mar 26 11:09 preempt
-rw-r--r--  1 root root 0 Mar 26 11:09 tunable_scaling
-rw-r--r--  1 root root 0 Mar 26 11:09 verbose
-rw-r--r--  1 root root 0 Mar 26 11:09 wakeup_granularity_ns

Use of brand name in standalone extension

Hi, I've created a minimal extension to support using system76-scheduler without pop-shell (as pop-shell is not available on extensions.gnome.org). It can be found here: https://github.com/mjakeman/s76-scheduler-plugin/

As part of the GNOME Extensions review guidelines:

Extensions MUST NOT include copyrighted or trademarked content without proof of express permission from the owner. Examples include: Brand Names and Phrases, Logos and Artwork, Audio, Video or Multimedia

Given that the project is called system76-scheduler, I'd just like to check that it's fine to use "System76 Scheduler" in the name of my extension? I've provided a disclaimer that it is unofficial/not affiliated in the description.

Feature Request: allow disabling CFS tweaks

It would be great to allow disabling CFS tweaks, as it would help when it's already handled manually, or more simply when one doesn't want to change the default which comes with its kernel.

A use_cfstweaks: true|false in the config.ron would be perfect

Feature Request: ability to suspend/resume scheduling changes

I do development on my system that uses the system76-scheduler daemon. The problem is that every so often - I want to do benchmark tests - and due to the way that the scheduler works - it will re-nice the processes. When I am not doing a benchmark - this is fine - since it gets changed on demand.

This would be nicer than trying to prevent the daemon from running.

Would it be possible to add a few dbus messages with the ability to make the scheduler suspend and resume changing priorities? This would allow me to use something like dbus-send during benchmarking and testing software.

Support running without tweakable scheduler if cfs profiles are disabled

Currently, if the kernel is built without SCHED_DEBUG, then the entire functionality of the scheduler is prevented - even if the CFS tweaking functionality is never used, especially seeing as cfs-profiles are set as disabled in the default configuration.

I ended up writing a small - and mediocre - patch to be able to get a binary that I can deploy on systems both with and without CFS tuning paths; (Not a rust developer, and not going to submit it as a PR as it should really handle the error properly on startup if cfs-profiles are enabled)

diff --git a/daemon/src/main.rs b/daemon/src/main.rs
index 9823dcb..d9d7bb1 100644
--- a/daemon/src/main.rs
+++ b/daemon/src/main.rs
@@ -158,7 +158,7 @@ async fn daemon(
         return reload(connection).await;
     }
 
-    let service = &mut service::Service::new(owner, SchedPaths::new()?);
+    let service = &mut service::Service::new(owner, SchedPaths::new().ok());
     service.reload_configuration();
 
     let (tx, mut rx) = tokio::sync::mpsc::channel(4);
diff --git a/daemon/src/service.rs b/daemon/src/service.rs
index a252f68..8f0df58 100644
--- a/daemon/src/service.rs
+++ b/daemon/src/service.rs
@@ -12,7 +12,7 @@ use system76_scheduler_config::scheduler::Condition;
 
 pub struct Service<'owner> {
     pub config: crate::config::Config,
-    cfs_paths: SchedPaths,
+    cfs_paths: Option<SchedPaths>,
     foreground_processes: Vec<u32>,
     foreground: Option<u32>,
     pipewire_processes: Vec<u32>,
@@ -21,7 +21,7 @@ pub struct Service<'owner> {
 }
 
 impl<'owner> Service<'owner> {
-    pub fn new(owner: LCellOwner<'owner>, cfs_paths: SchedPaths) -> Self {
+    pub fn new(owner: LCellOwner<'owner>, cfs_paths: Option<SchedPaths>) -> Self {
         Self {
             config: crate::config::Config::default(),
             cfs_paths,
@@ -273,7 +273,7 @@ impl<'owner> Service<'owner> {
             return;
         }
 
-        crate::cfs::tweak(&self.cfs_paths, config);
+        crate::cfs::tweak(&self.cfs_paths.as_ref().unwrap(), config);
     }
 
     pub fn cfs_on_battery(&self, on_battery: bool) {

What are the Kernel option requirements

When I try to start the systemd service, the following error appears:

Error: kernel does not support tweaking the scheduler

I'm using the Vanilla 5.15.x kernel. I'd like to know what kernel options systemd76-scheduler need.

Add benchmark to README.md file

In readme file I see

These changes result in a noticeable improvement in the experienced smoothness
and performance of applications and games.

but how big is improvement on older/newer machines? 0.05, 0.5, 5 or 50%

Adding benchmark like https://flightlessmango.com/benchmarks/rM7Rfu4swVQ would let users know what kind of increase (or decrease) in performance they can expect

Tagging releases

Hi!

I'm planning to add a build recipe for this package in the Arch User Repository (unless someone beat me to it), so it'd be really helpful if you added tags to releases.

Thank you very much!

Only the main thread of a process gets reniced properly if the process had a manual niceness assignment

Say a program foo starts and then spawns 3 more threads.

And in /etc/system76-scheduler/assignments/foo.ron

{
  3: [
    "foo",
  ],
}

Then unless system76-scheduler happened to renice before the threads spawned, only main thread of foo is assured to be reniced to 3.
The other threads would be left at the original niceness (typically 0, or 5 if it matched the background process renicing and that is enabled as well)

Reproduction

Add to some assignment .ron file

{
  -4: [
        "gnome-system-monitor",
],
}

Start gnome-system-monitor

Look at the niceness of the threads. The command ps -L -o pid,comm,lwp,nice --pid $(pidof gnome-system-monitor) should do it.

See how most likely only the main thread is at niceness -4, and the others remain at 0 niceness.

On my machine, the output was

    PID COMMAND             LWP  NI
 370993 gnome-system-mo  370993  -4
 370993 gmain            370995   0
 370993 dconf worker     370996   0
 370993 gdbus            370997   0

Concept decent; execution needs work

After wrangling with PopOS for several months, I finally figured out that it was this daemon that was causing issues. Don't get me wrong - I like the concept. The execution, however, causes me major pain. In no particular order:

  1. I was unable to see why process priorities were being changed. I didn't spy anything in the logs, nor did I spy anything obvious in the system daemons either (because when I see 'scheduler daemon' I think of 'figuring out ordering/timing/priority of starting new background tasks I own', not 'managing priorities of existing random other tasks not owned by me' - admittedly far more obvious in hindsight).
    • At least log something (rate-limited, of course.)
    • Looking at the logs with the benefit of hindsight, it does log something...
      • ...on boot only...
      • ...into the system log not the user log...
      • ...and the log message implies that it's only setting the priority of a specific few process names, not everything.
  2. nice / renice just flat-out doesn't work. Oh, it seems to work... for a few seconds. Then reverts back to the old priority.
    • Solution: if you're going to fiddle with priorities, please make sure that if a priority is manually changed that it won't be fiddled with again.
      • Please also ensure that this handles the case of "someone switches the priority of a background process to a priority that happens to match the priority you assign foreground processes" (and vice versa.)
      • Please also ensure this doesn't fiddle with priorities of newly spawned subprocesses of said renice'd task.
  3. Speaking of nice/renice, having the default foreground priority (-5) be lower than the minimum user-accessible priority (0) results in a lot of pain.
    • Looking at the config file now, I note that you can change the configuration from -5. However, see point 1, above.
    • I'd suggest putting the defaults at 15 / 5 instead of 5 / -5. That way a user can launch a process at a higher priority than the default priority.
  4. In general, there's no easy way to temporarily override the daemon's decision for a task, or to get visibility into why the daemon is making changes.
  5. Priority inversions. So many priority inversions.
    • Fixing this requires a more capable configuration system that can express dependencies between processes, and a fair bit of work to actually put said dependencies into the configuration.
  6. "The" foreground task is a poor proxy for what I actually care about.
    • My usual style of 'several terminals on top running things most of the time, and then flipping to Firefox for a few seconds before flipping back' unfortunately in practice often results in noticeable jank when switching from a terminal pegging the cpu to Firefox.
      • I think part of this is the following chain: background -> low priority -> process not running very often at all -> process gets mostly swapped out -> hiccough when window refocused. (Linux doesn't explicitly swap out low-priority processes, but the way kswapd interacts with process scheduling comes out to the same thing.)
      • Maybe prioritize all visible windows instead of simply 'the' currently focused window?
      • Maybe have a heuristic to keep processes that have been visible e.g. 10% of the last ten minutes foreground priority? (Or 'just' put recently-foreground'd processes in a cgroup with vm.swappiness=0? If you do this, make sure that if the process is already in a cgroup you make a nested cgroup, not clobber the existing one.)
    • In general, this style of daemon doesn't play well with anything that is conditionally interactive (e.g. if I'm playing audio via Firefox, I want it to remain at a decent priority regardless of if it's in the background - but I don't always want Firefox to remain at a boosted priority.)
      • Other examples are java or python or lua. Should java be prioritized even if in the background? Answer: it depends entirely on what it's actually running.
      • Some of this may be solvable (with some false positives / false negatives) via e.g. hooking into the audio system to see what is currently using audio sources/sinks.

All told, on my system, with the sorts of workloads I run (as I type this I've got the cpu pegged with two separate 8-core bsat solver instances, for instance, both set to nice=19 and in a 24GB-max cgroup), system76-scheduler actually makes responsiveness significantly worse than default.

(For reference: this is a Oryx Pro (9, not 10) with 32GB RAM.)

For now, I've systemctl stop com.system76.Scheduler.service / systemctl disable com.system76.Scheduler.service / sudo apt remove system76-scheduler'd it (and will continue to do so on all machines I control as necessary); I will revisit this in future if the worst of the warts are removed.

I figured you might like feedback as to why I disabled it, as opposed to just 'one less user; why? ¯\_(ツ)_/¯'.

Simple build instructions for use on another distro?

May we have some basic build instructions for building this? I'm using openSUSE and I had sucessfully installed it. However I had a disk failure and now I'm somehow unable to find out how I did it, or my notes either. I'd like to contribute back afterwards.

Feature Request: Systemd services that have a `Nice=` value given explicitly should not be touched by default background priority adjustments

SystemD allows configuration of services with a Nice property. Which, to little surprise, adjusts the process(es) niceness on launch.

For services that have such a Nice= explicitly given, system76-scheduler shouldn't subject them to the default background priority adjustments. Since in that case the service probably is lower or higher priority for good reason.

(I'm classifying this as a feature request, not a bug, due to the sheer scope of work needed just to "fix" this bug)

For a bit more nuance, we could have

  • Services configured with a Nice of <0 should never have their niceness raised above the configured value.
  • Services configured with a Nice of >0 should never have their niceness lowered below the configured value (unless it becomes the foreground process...somehow).

IMO, per-process assignments in assignments should override systemd configured niceness by default.
Maybe introduce a new config option (false by default) to have systemd managed services still take priority over process assignments.

I don't know of a current (efficient) way to tell the difference between an explicitly set Nice=0 vs the Nice=0 coming from the default of that property (either case shows Nice=0)
I'd be fine with treating Nice=0 the same as unset though.

There is a libsystemd crate you can probably use to avoid the pitfalls of parsing command line output.

(If you ever want support for other distros that don't mandate SystemD init, you will probably want to introduce a build configuration option to build without systemd support)

Make cfs-profiles configuration clearer

Currently, the CFS tuning happens when the option is enabled and what it does is switching between the two profiles when the power source is either battery or ac. However, there's no place in the config file where that information is stated:

// Latency profiles the kernel's Completely Fair Scheduler
cfs-profiles enable=true {
    // The kernel-default values which are ideal for battery life and servers
    default latency=6 nr-latency=8 wakeup-granularity=1.0 bandwidth-size=5 preempt="voluntary"

    // Zen CFS parameters that make the desktop more responsive
    responsive latency=4 nr-latency=10 wakeup-granularity=0.5 bandwidth-size=3 preempt="full"
}

Ideally, I'd swap the profile names default and responsive to battery and ac respectively, so they reflect better what the scheduler is actually doing. An alternative would be to simply add a comment making that clearer.

Would you be willing to accept patches for either?

Syslog is flooded with `setting foreground process nnn`

After the latest update system76-scheduler 1.1.0~1651696814~22.04~cbccc2e my /var/log/syslog is being flooded with ansi-escaped (!) log messages every time I switch focus to a different window:

May  5 17:43:06 amperama system76-scheduler[1415]: #033[32m INFO#033[0m #033[2msystem76_scheduler#033[0m#033[2m:#033[0m setting foreground process 15065

Is there a way to lower the log level?

Running Pop OS 22.04 LTS.

TIA

Setting background and foreground to None in config.ron causes explicit process assignments to be ignored

Setting your config.ron to have

{
  background: None,
  foreground: None,
}

Causes any explicit process assignments (assignments.ron and others) to be not applied.

Seems to be a regression of #12, in which it was stated the desired behavior was to still allow per-process assignments to apply even with None.

If only background is None, then per-process mappings are only applied when a process goes into the foreground.
The opposite for foreground.

CPU_PRIORITY is a misnomer

What you specify this way is the nice value, not SCHED_FIFO/SCHED_RR priority.

But actually it would be neat to have the ability to venture beyond the SCHED_OTHER policy: like, say, assign SCHED_IDLE to compilers etc. instead of assuming niceness 19 plus idle i/o is low enough for everybody. Not sure about SCHED_RR/SCHED_FIFO, since those come with foot-guns attached, but maybe allow even those (not in the default config though). I wonder if this direction has ever been explored in this project?

Why setuid binary?

Why is /usr/bin/system76-scheduler installed as a setuid binary (chmod 04755)? It runs as a system service under root, doesn’t it?

Is it possible to run it as a non-privileged user (without setuid ofc)? Also, what linux capabilities does it actually need?

Values for min_granularity_ns and wakeup_granularity_ns read as 0

Following #20 being merged, I've noticed that reading min_granularity_ns and wakeup_granularity_ns with cat shows their values as 0.

[root@81x2 ~]# cat /proc/sys/kernel/sched_cfs_bandwidth_slice_us /sys/kernel/debug/sched/latency_ns /sys/kernel/debug/sched/min_granularity_ns /sys/kernel/debug/sched/wakeup_granularity_ns
3000
12000000
0
0
[root@81x2 ~]# 

This was tested on Fedora 35 with secure boot disabled, which permits writing to the values. I do have it installed to /usr/local as opposed to /usr while also installing to sbin over bin following previous issues with a utility that set zen-kernel's CFS values, but I'm decently confident that this is not a contributing factor as the values read correctly prior to #20 with this same setup.

I'm not entirely sure something is wrong beyond those values showing as 0 as I do not seem to have had peformance regressions or otherwise.

Child foreground niceness sometimes not applied

Steps to reproduce:

  • Fresh boot/login
  • Open a terminal, run top, open Firefox and Nautilus
  • Observe in top that the foreground/background nicenesses work when switching between Firefox and Nautilus
  • Switch focus to the first terminal, then open a second terminal
  • Run stress -c 1
  • Observe that stress (and sometimes top) have the background niceness of 6, even though the terminal with stress is focused.
  • Switch focus away from the terminal and back; the niceness of stress switches to 0.

Screenshot from 2023-05-01 13-05-54

This may occur more often if stress is run very quickly after switching focus to the terminal(s). However, it's not just a delay before the foreground niceness is applied; it's never applied until another focus switch when this issue occurs.

This is not caused by or fixed by #92.

Questions about Wayland

I'm using wayland instead of xorg in my pop 20.04, do I need to modify my /usr/share/system76-scheduler/assignments/default.ron like this ?

{
// High priority
-5: [
    "gnome-shell",
    "kwin",
    "Xorg",
    "Xwayland"     <<<===============
],
// Absolute lowest priority
19: [
    "c++",
    "cargo",
    "clang",
    "cpp",
    "g++",
    "gcc",
    "lld",
    "make",
    "rustc",
]}

Also, is there any reason Wayland is disabled from the cog wheel from pop 20.04 (need to edit /etc/gdm3/custom.conf file to enable), curious if it's disabled because of any regressions or conflicts with pop os.

Finally, thank you for your such great contributions to the linux community <3

Print out configuration issues on stderr

Print out a warning about Configuration issues to stderr (probably add --silent option too for the CLI for those that don't even want that printed)
Configuration issues such as:

  • a .ron file that doesn't parse as a valid Rust syntax datatype (syntax errors, etc)
  • a .ron file that had unexpected types (like an assignments/foo.ron whose contents is something like ["a", "b"], aka an Array literal instead of a Map literal
  • configuration settings that are valid in terms of types, but don't actually make sense. Like a cpu scheduler profile that is unrecognized (neither '

The daemon should probably keep track of which .ron files it has printed such a warning about in the past, and not warn about those again unless the modification time of the file has been updated since the last printed warning.
That way it doesn't repeat this warning every time system76-scheduler "runs a renice cycle".

Reproduction:

Create a file /etc/system76-scheduler/assignments/invalid.ron
And populate it with something with a blatantly invalid syntax like

{
  f:
}

(no quotes around f and no symbol f is currently defined, no value listed)

Restart the com.system76.Scheduler.service service.
Note how nothing shows up in journalctl (journalctl -eu com.system76.Scheduler.service)

Also, running RUST_LOG=system76-scheduler=warn system76-scheduler daemon manually, no warnings print out.

How to set `EXECSNOOP_PATH` to `/usr/share/bcc/tools/execsnoop` on Fedora 36

Hi,

I'm using Fedora 36 and how I cannot find execsnoop-bpfcc, so I installed bcc which contains execsnoop. I'm not fully understand what are the difference they are.

I checked this PR #41, but I still don't understand how to config EXECSNOOP_PATH.

EXECSNOOP_PATH=/usr/share/bcc/tools/execsnoop before running just does not work for me, see these errors:

error: must set EXECSNOOP_PATH env to execsnoop-bpfcc path
  --> execsnoop/src/lib.rs:42:18
   |
42 |       Command::new(std::env!(
   |  __________________^
43 | |         "EXECSNOOP_PATH",
44 | |         "must set EXECSNOOP_PATH env to execsnoop-bpfcc path"
45 | |     ))
   | |_____^
   |
   = note: this error originates in the macro `std::env` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `execsnoop` due to previous error
error: Recipe `all` failed on line 24 with exit code 101

And advice?

Set preempt to full on the responsive profile

Fedora is thinking about making the switch to full by default to get lower latency scheduling on desktops and workstations. This might be worth adding to the responsive profile.

echo full | sudo tee /sys/kernel/debug/sched/preempt

On occasion, very high CPU usage

Not so long ago I started using Wayland and sway WM, anyway, while running Overwatch 2, I noticed one of my CPU cores maxing out. That's unusual. With a quick trip into gnome-system-monitor, I found that the 76 manager was using 10% of my Ryzen 5 3600. That's abnormally high, and I don't really know what's up with it. But that event made me close it out for a while, and sometimes it'll rocket itself back up to that level.

CFS tweaks might hurt performance

  1. Value for "minimum_granularity" is not correct. It should be calculated like with such formula
    sched_min_granularity_ns=sched_latency_ns/sched_nr_latency
    sched_nr_latency = 8 on mainline
    So for latency: 4ns:
    minimum_granularity=4/8=0.5
    For Zen kernel minimum_granularity=0.4 is correct because maintainers change "sched_nr_latency" value to "10" .
  2. Reduction of "CPU migration cost" (sched_migration_cost) might hurt performance under load. That's the reason why this tweak has already been dropped for Zen/Liquorix kernels

Fullscreen applications and applications that use the webcam/mic should always be counted as foreground.

Hi,

Running Pop!_OS 22.04 to try out the scheduler on lower end hardware (Haswell ultrabook i7 processor, 2C/4T). Providing some feedback:

  • If I'm on a VoIP call (Discord, Telegram), my intuition is that the call should always be counted as a foreground process whilst the call is happening.
  • Similarly, any application that is full-screen should be considered as a foreground process, like a video maximised in a browser.

In both cases, you get video/audio hitches when interacting with an application on a second screen, which detracts from the experience.

I'd offer a PR but my experience with Rust and dbus is minimal.

Hope this helps!

CPU thread 100%

Hi,
Just updated the OS and restarted my Lemur Pro and the daemon uses 100% of one of the CPU threads.
I let it run 15 minutes then stopped the service.
Our company owns 5 identical machines, they all had the same issue with execsnoop-bpfcc

/usr/bin/system76-scheduler daemon
_ [execsnoop-bpfcc] < defunct >

System76 Lemur Pro/Lemur Pro, BIOS 2021-07-20_93c2809 07/20/2021

NAME="Pop!_OS"
VERSION="22.04 LTS"
ID=pop
ID_LIKE="ubuntu debian"
PRETTY_NAME="Pop!_OS 22.04 LTS"
VERSION_ID="22.04"
HOME_URL="https://pop.system76.com"
SUPPORT_URL="https://support.system76.com"
BUG_REPORT_URL="https://github.com/pop-os/pop/issues"
PRIVACY_POLICY_URL="https://system76.com/privacy"
VERSION_CODENAME=jammy
UBUNTU_CODENAME=jammy
LOGO=distributor-logo-pop-os

Project name (System76 vs. Pop)

Was there a reason this project was named system76-scheduler instead of pop-scheduler? Is anything about the project specific to System76 hardware? (This question just occurred to me while reading a news article about the release, and thinking about the relation between this and pop-shell, pop-launcher, etc.)

FAHClient is listed twice in auto.ron

In auto.ron provided by system76-scheduler v1.1.0 FAHClient is listed first in low (9):

9: [
...
    "fwupd",
    "FAHClient",
...

And then in absolutely low (19):

19: [
    "boinc",
    "FAHClient",
    "FAHCoreWrapper",
...

Conflicts with gamemode (and foreground apps getting background priorities)

Noticed that a few things (mostly games) were running slightly poorer than they used to, like minor stutters or vastly higher minimum/99% frame times. Tried to apply gamemoderun but quickly found that their priority was getting lowered after the fact.

Gamemode keeps track of every process it's active for, and it can be asked over DBUS about which processes it has registered, e.g.

# dbus-send --session --print-reply --dest=com.feralinteractive.GameMode --type=method_call /com/feralinteractive/GameMode com.feralinteractive.GameMode.QueryStatusByPID int32:$PPID int32:1155695
method return time=1654503762.757012 sender=:1.393 -> destination=:1.12203 serial=11575 reply_serial=2
   int32 2

(send own PID, pid of process to check if gamemode is active for, returns 1 when gamemode is active, but not for that PID, 2 when that proc is registered under gamemode, and -1 if not active)

I think S76-scheduler should avoid setting priorities on processes already managed by gamemode.

I am not sure why, but even while an application/game is in focus, S76-scheduler assigns it a background nice 5 even though it's the foreground application. This is 100% reproducible using a steam game with Proton configured to use gamemode. In this sense, I would consider having the foreground application/game's priority lowered a bug.

A potentially easier workaround would be to just disable the S76-scheduler while gamemode is active, but that seems like a somewhat poorer solution if DBUS communication is possible. (Though it's what I will recommend to fellow gamers until a better option is available)

Using `nice` from Tilix does nothing

For terminals in focus, all their descendants acquire the same priority values when changed, however this makes using nice for a command completely useless.

Two commands being tested: stress -c 8 and nice stress -c 8 both end up with foreground priority/niceness -5, while obviously the niced command should not be given priority.

Demo, foreground window name in top left:

2022-06-07.01-36-00.mp4

Support process niceness assignments even if foreground: or background: is set to None

For my machine, I don't want system76-scheduler to mess with my niceness by default. Only when it explicitly matches a command name in some file in system76-schedule/assignments.

So to do this, I used /etc/system76-schedule/assignments/my_assignments.ron, and set my /etc/system76-schedule/config.ron to:

(
background: None,

foreground: None,
)

system76-schedule correctly interpreted this a not touching background or foreground process niceness by default.
Unfortunately, is also tells it to not touch background or foreground process niceness at all.

The behavior I expected was "Does not touch background or foreground process, unless there is a match in the assignments."

So can that be a thing?
If people are relying on the old behavior (None telling system76-scheduler to skip that category entirely), then perhaps some new value we can assign that it will know "Don't touch it, but still look at the assignments and take action if found there". Like

(
background: Some<AssignmentsOnly>,
// Where AssignmentsOnly is an i8 constant that is way outside the valid nice range, or some other type,
// that system76-scheduler will give this treatment to if it sees it.

foreground: Some<AssignmentsOnly>,
)

or something.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.