1{ lib, config, pkgs, ... }:
2
3with lib;
4let
5 cfg = config.modules.desktop;
6
7 concat = concatMapStringsSep "," toString;
8 performance = concat cfg.affinity.performanceCores;
9 efficiency = concat cfg.affinity.efficiencyCores;
10in {
11 options.modules.desktop.affinity = {
12 enable = mkOption {
13 default = cfg.enable;
14 example = true;
15 description = "Tweak CPU affinity into performance and efficiency core slices";
16 type = types.bool;
17 };
18
19 oomd = mkOption {
20 default = false;
21 example = true;
22 description = "Enable systemd-oomd";
23 type = types.bool;
24 };
25
26 performanceCores = mkOption {
27 type = with types; listOf ints.unsigned;
28 default = [ ];
29 description = "List of performance CPUs";
30 };
31
32 efficiencyCores = mkOption {
33 type = with types; listOf ints.unsigned;
34 default = [ 0 1 2 3 ];
35 description = "List of efficiency CPUs";
36 };
37
38 isolateNixDaemon = mkOption {
39 default = cfg.affinity.enable;
40 type = types.bool;
41 };
42 };
43
44 config = mkIf cfg.affinity.enable {
45 boot.kernelParams = [ "rcu_nocbs=all" ]
46 ++ optionals (efficiency != "") [ "irqaffinity=${efficiency}" ]
47 ++ optionals (performance != "") [ "nohz_full=${performance}" ];
48
49 systemd = {
50 oomd.enable = false;
51 user.slices = {
52 background.sliceConfig = {
53 AllowedCPUs = efficiency;
54 CPUWeight = 80;
55 IOWeight = 60;
56 };
57 session.sliceConfig = {
58 StartupAllowedCPUs = mkIf (performance != "") "${efficiency},${performance}";
59 AllowedCPUs = efficiency;
60 IOWeight = 90;
61 };
62 app.sliceConfig.IOWeight = 100;
63 };
64 slices = {
65 system.sliceConfig = {
66 AllowedCPUs = efficiency;
67 IOWeight = 120;
68 };
69 nix.sliceConfig = mkIf cfg.affinity.isolateNixDaemon {
70 CPUQuota = "80%";
71 IOWeight = 90;
72 };
73 };
74 services = {
75 nix-daemon.serviceConfig = mkIf cfg.affinity.isolateNixDaemon {
76 Slice = "nix.slice";
77 OOMScoreAdjust = 950;
78 };
79 "user@" = {
80 overrideStrategy = "asDropin";
81 serviceConfig.Delegate = "cpuset";
82 };
83 };
84 };
85
86 assertions = singleton {
87 assertion = mutuallyExclusive cfg.affinity.performanceCores cfg.affinity.efficiencyCores;
88 message = "Performance and efficiency CPU cores must not overlap";
89 };
90 };
91}