Unverified Commit bdb79914 authored by github-actions[bot]'s avatar github-actions[bot] Committed by GitHub
Browse files

Merge master into staging-next

parents 2f777e46 e4ad8930
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -181,6 +181,8 @@ In addition to numerous new and upgraded packages, this release has the followin

- The option `i18n.inputMethod.fcitx5.enableRimeData` has been removed. Default RIME data is now included in `fcitx5-rime` by default, and can be customized using `fcitx5-rime.override { rimeDataPkgs = [ pkgs.rime-data, package2, ... ]; }`

- The udev hwdb.bin file is now built with systemd-hwdb rather than the [deprecated "udevadm hwdb"](https://github.com/systemd/systemd/pull/25714). This may impact mappings where the same key is defined in multiple matching entries. The updated behavior will select the latest definition in case of conflict. In general, this should be a positive change, as the hwdb source files are designed with this ordering in mind. As an example, the mapping of the HP Dev One keyboard scan code for "mute mic" is corrected by this update. This change may impact users who have worked-around previously incorrect mappings.

- Kime has been updated from 2.5.6 to 3.0.2 and the `i18n.inputMethod.kime.config` option has been removed. Users should use `daemonModules`, `iconColor`, and `extraConfig` options under `i18n.inputMethod.kime` instead.

- `tut` has been updated from 1.0.34 to 2.0.0, and now uses the TOML format for the configuration file instead of INI. Additional information can be found [here](https://github.com/RasmusLindroth/tut/releases/tag/2.0.0).
+1 −0
Original line number Diff line number Diff line
@@ -444,6 +444,7 @@
  ./services/desktops/pipewire/wireplumber.nix
  ./services/desktops/profile-sync-daemon.nix
  ./services/desktops/system-config-printer.nix
  ./services/desktops/system76-scheduler.nix
  ./services/desktops/telepathy.nix
  ./services/desktops/tumbler.nix
  ./services/desktops/zeitgeist.nix
+296 −0
Original line number Diff line number Diff line
{ config, lib, pkgs, ... }:

let
  cfg = config.services.system76-scheduler;

  inherit (builtins) concatStringsSep map toString attrNames;
  inherit (lib) boolToString types mkOption literalExpression mdDoc optional mkIf mkMerge;
  inherit (types) nullOr listOf bool int ints float str enum;

  withDefaults = optionSpecs: defaults:
    lib.genAttrs (attrNames optionSpecs) (name:
      mkOption (optionSpecs.${name} // {
        default = optionSpecs.${name}.default or defaults.${name} or null;
      }));

  latencyProfile = withDefaults {
    latency = {
      type = int;
      description = mdDoc "`sched_latency_ns`.";
    };
    nr-latency = {
      type = int;
      description = mdDoc "`sched_nr_latency`.";
    };
    wakeup-granularity = {
      type = float;
      description = mdDoc "`sched_wakeup_granularity_ns`.";
    };
    bandwidth-size = {
      type = int;
      description = mdDoc "`sched_cfs_bandwidth_slice_us`.";
    };
    preempt = {
      type = enum [ "none" "voluntary" "full" ];
      description = mdDoc "Preemption mode.";
    };
  };
  schedulerProfile = withDefaults {
    nice = {
      type = nullOr (ints.between (-20) 19);
      description = mdDoc "Niceness.";
    };
    class = {
      type = nullOr (enum [ "idle" "batch" "other" "rr" "fifo" ]);
      example = literalExpression "\"batch\"";
      description = mdDoc "CPU scheduler class.";
    };
    prio = {
      type = nullOr (ints.between 1 99);
      example = literalExpression "49";
      description = mdDoc "CPU scheduler priority.";
    };
    ioClass = {
      type = nullOr (enum [ "idle" "best-effort" "realtime" ]);
      example = literalExpression "\"best-effort\"";
      description = mdDoc "IO scheduler class.";
    };
    ioPrio = {
      type = nullOr (ints.between 0 7);
      example = literalExpression "4";
      description = mdDoc "IO scheduler priority.";
    };
    matchers = {
      type = nullOr (listOf str);
      default = [];
      example = literalExpression ''
        [
          "include cgroup=\"/user.slice/*.service\" parent=\"systemd\""
          "emacs"
        ]
      '';
      description = mdDoc "Process matchers.";
    };
  };

  cfsProfileToString = name: let
    p = cfg.settings.cfsProfiles.${name};
  in
    "${name} latency=${toString p.latency} nr-latency=${toString p.nr-latency} wakeup-granularity=${toString p.wakeup-granularity} bandwidth-size=${toString p.bandwidth-size} preempt=\"${p.preempt}\"";

  prioToString = class: prio: if prio == null then "\"${class}\"" else "(${class})${toString prio}";

  schedulerProfileToString = name: a: indent:
    concatStringsSep " "
      (["${indent}${name}"]
       ++ (optional (a.nice != null) "nice=${toString a.nice}")
       ++ (optional (a.class != null) "sched=${prioToString a.class a.prio}")
       ++ (optional (a.ioClass != null) "io=${prioToString a.ioClass a.ioPrio}")
       ++ (optional ((builtins.length a.matchers) != 0) ("{\n${concatStringsSep "\n" (map (m: "  ${indent}${m}") a.matchers)}\n${indent}}")));

in {
  options = {
    services.system76-scheduler = {
      enable = lib.mkEnableOption (lib.mdDoc "system76-scheduler");

      package = mkOption {
        type = types.package;
        default = config.boot.kernelPackages.system76-scheduler;
        defaultText = literalExpression "config.boot.kernelPackages.system76-scheduler";
        description = mdDoc "Which System76-Scheduler package to use.";
      };

      useStockConfig = mkOption {
        type = bool;
        default = true;
        description = mdDoc ''
          Use the (reasonable and featureful) stock configuration.

          When this option is `true`, `services.system76-scheduler.settings`
          are ignored.
        '';
      };

      settings = {
        cfsProfiles = {
          enable = mkOption {
            type = bool;
            default = true;
            description = mdDoc "Tweak CFS latency parameters when going on/off battery";
          };

          default = latencyProfile {
            latency = 6;
            nr-latency = 8;
            wakeup-granularity = 1.0;
            bandwidth-size = 5;
            preempt = "voluntary";
          };
          responsive = latencyProfile {
            latency = 4;
            nr-latency = 10;
            wakeup-granularity = 0.5;
            bandwidth-size = 3;
            preempt = "full";
          };
        };

        processScheduler = {
          enable = mkOption {
            type = bool;
            default = true;
            description = mdDoc "Tweak scheduling of individual processes in real time.";
          };

          useExecsnoop = mkOption {
            type = bool;
            default = true;
            description = mdDoc "Use execsnoop (otherwise poll the precess list periodically).";
          };

          refreshInterval = mkOption {
            type = int;
            default = 60;
            description = mdDoc "Process list poll interval, in seconds";
          };

          foregroundBoost = {
            enable = mkOption {
              type = bool;
              default = true;
              description = mdDoc ''
                Boost foreground process priorities.

                (And de-boost background ones).  Note that this option needs cooperation
                from the desktop environment to work.  On Gnome the client side is
                implemented by the "System76 Scheduler" shell extension.
              '';
            };
            foreground = schedulerProfile {
              nice = 0;
              ioClass = "best-effort";
              ioPrio = 0;
            };
            background = schedulerProfile {
              nice = 6;
              ioClass = "idle";
            };
          };

          pipewireBoost = {
            enable = mkOption {
              type = bool;
              default = true;
              description = mdDoc "Boost Pipewire client priorities.";
            };
            profile = schedulerProfile {
              nice = -6;
              ioClass = "best-effort";
              ioPrio = 0;
            };
          };
        };
      };

      assignments = mkOption {
        type = types.attrsOf (types.submodule {
          options = schedulerProfile { };
        });
        default = {};
        example = literalExpression ''
          {
            nix-builds = {
              nice = 15;
              class = "batch";
              ioClass = "idle";
              matchers = [
                "nix-daemon"
              ];
            };
          }
        '';
        description = mdDoc "Process profile assignments.";
      };

      exceptions = mkOption {
        type = types.listOf str;
        default = [];
        example = literalExpression ''
          [
            "include descends=\"schedtool\""
            "schedtool"
          ]
        '';
        description = mdDoc "Processes that are left alone.";
      };
    };
  };

  config = {
    environment.systemPackages = [ cfg.package ];
    services.dbus.packages = [ cfg.package ];

    systemd.services.system76-scheduler = {
      description = "Manage process priorities and CFS scheduler latencies for improved responsiveness on the desktop";
      wantedBy = [ "multi-user.target" ];
      path = [
        # execsnoop needs those to extract kernel headers:
        pkgs.kmod
        pkgs.gnutar
        pkgs.xz
      ];
      serviceConfig = {
        Type = "dbus";
        BusName= "com.system76.Scheduler";
        ExecStart = "${cfg.package}/bin/system76-scheduler daemon";
        ExecReload = "${cfg.package}/bin/system76-scheduler daemon reload";
      };
    };

    environment.etc = mkMerge [
      (mkIf cfg.useStockConfig {
        # No custom settings: just use stock configuration with a fix for Pipewire
        "system76-scheduler/config.kdl".source = "${cfg.package}/data/config.kdl";
        "system76-scheduler/process-scheduler/00-dist.kdl".source = "${cfg.package}/data/pop_os.kdl";
        "system76-scheduler/process-scheduler/01-fix-pipewire-paths.kdl".source = ../../../../pkgs/os-specific/linux/system76-scheduler/01-fix-pipewire-paths.kdl;
      })

      (let
        settings = cfg.settings;
        cfsp = settings.cfsProfiles;
        ps = settings.processScheduler;
      in mkIf (!cfg.useStockConfig) {
        "system76-scheduler/config.kdl".text = ''
          version "2.0"
          autogroup-enabled false
          cfs-profiles enable=${boolToString cfsp.enable} {
            ${cfsProfileToString "default"}
            ${cfsProfileToString "responsive"}
          }
          process-scheduler enable=${boolToString ps.enable} {
            execsnoop ${boolToString ps.useExecsnoop}
            refresh-rate ${toString ps.refreshInterval}
            assignments {
              ${if ps.foregroundBoost.enable then (schedulerProfileToString "foreground" ps.foregroundBoost.foreground "    ") else ""}
              ${if ps.foregroundBoost.enable then (schedulerProfileToString "background" ps.foregroundBoost.background "    ") else ""}
              ${if ps.pipewireBoost.enable then (schedulerProfileToString "pipewire" ps.pipewireBoost.profile "    ") else ""}
            }
          }
        '';
      })

      {
        "system76-scheduler/process-scheduler/02-config.kdl".text =
          "exceptions {\n${concatStringsSep "\n" (map (e: "  ${e}") cfg.exceptions)}\n}\n"
          + "assignments {\n"
          + (concatStringsSep "\n" (map (name: schedulerProfileToString name cfg.assignments.${name} "  ")
            (attrNames cfg.assignments)))
          + "\n}\n";
      }
    ];
  };

  meta = {
    maintainers = [ lib.maintainers.cmm ];
  };
}
+1 −1
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ let

      echo "Generating hwdb database..."
      # hwdb --update doesn't return error code even on errors!
      res="$(${pkgs.buildPackages.udev}/bin/udevadm hwdb --update --root=$(pwd) 2>&1)"
      res="$(${pkgs.buildPackages.systemd}/bin/systemd-hwdb --root=$(pwd) update 2>&1)"
      echo "$res"
      [ -z "$(echo "$res" | egrep '^Error')" ]
      mv etc/udev/hwdb.bin $out
+468 −456

File changed.

Preview size limit exceeded, changes collapsed.

Loading