dot

vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks

261 lines9600 bytesNix
1# What CachyOS adds on top of plain Arch: its kernel and the cachyos-settings
2# package (sysctl, udev rules, systemd defaults), ported file by file. The CachyOS
3# file each part comes from is named next to it, so they can be compared when
4# CachyOS changes something.
5#
6# Not ported, because it does nothing on this machine: the laptop audio power
7# saving and touchpad rules, the old-Radeon (SI/CIK) amdgpu options, and
8# debuginfod. Snapper root snapshots are replaced by NixOS generations: every
9# rebuild is a boot menu entry you can go back to.
10{
11 inputs,
12 lib,
13 pkgs,
14 ...
15}:
16let
17 # cachyos-settings: /usr/bin/game-performance. Runs a game with the
18 # "performance" power profile held, and the screensaver inhibited. Use it as
19 # a Steam launch option: game-performance %command%
20 game-performance = pkgs.writeShellApplication {
21 name = "game-performance";
22 runtimeInputs = [ pkgs.power-profiles-daemon pkgs.systemd ];
23 text = ''
24 if ! powerprofilesctl list | grep -q 'performance:'; then
25 exec "$@"
26 fi
27 if [ -n "''${GAME_PERFORMANCE_SCREENSAVER_ON:-}" ]; then
28 exec powerprofilesctl launch -p performance \
29 -r "Launched with CachyOS game-performance utility" -- "$@"
30 else
31 exec systemd-inhibit --why "CachyOS game-performance is running" powerprofilesctl launch \
32 -p performance -r "Launched with CachyOS game-performance utility" -- "$@"
33 fi
34 '';
35 };
36
37 # cachyos-settings: /usr/bin/dlss-swapper. Steam launch option:
38 # dlss-swapper %command%
39 dlss-swapper = pkgs.writeShellScriptBin "dlss-swapper" ''
40 export PROTON_ENABLE_NGX_UPDATER=1
41 export DXVK_NVAPI_DRS_NGX_DLSS_RR_OVERRIDE=on
42 export DXVK_NVAPI_DRS_NGX_DLSS_SR_OVERRIDE=on
43 export DXVK_NVAPI_DRS_NGX_DLSS_FG_OVERRIDE=on
44 export DXVK_NVAPI_DRS_NGX_DLSS_RR_OVERRIDE_RENDER_PRESET_SELECTION=render_preset_latest
45 export DXVK_NVAPI_DRS_NGX_DLSS_SR_OVERRIDE_RENDER_PRESET_SELECTION=render_preset_latest
46 exec "$@"
47 '';
48in
49{
50 # --- Kernel ----------------------------------------------------------------
51
52 # The overlay pins the kernel to the nixpkgs it was built with, so it comes
53 # from the binary cache instead of compiling.
54 nixpkgs.overlays = [ inputs.nix-cachyos-kernel.overlays.pinned ];
55
56 nix.settings = {
57 substituters = [ "https://attic.xuyh0120.win/lantian" ];
58 trusted-public-keys = [ "lantian:EeAUQ+W+6r7EtwnmYjeVwx5kOGEBpjlBfPlzGlTNvHc=" ];
59 };
60
61 # Same build as linux-cachyos on CachyOS's znver4 repo: EEVDF scheduler,
62 # 1000 Hz, full preemption, Clang ThinLTO, tuned for Zen 4 (also right for
63 # this Zen 5 CPU, as on CachyOS).
64 boot.kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest-lto-zen4;
65
66 boot.kernelParams = [
67 "nowatchdog"
68 # cachyos-settings: udev/rules.d/30-zram.rules turns zswap off once zram is
69 # up; it is always up here, so it is simply off from boot.
70 "zswap.enabled=0"
71 ];
72
73 # modprobe.d/blacklist.conf
74 boot.blacklistedKernelModules = [
75 "iTCO_wdt"
76 "sp5100_tco"
77 ];
78
79 # modules-load.d/ntsync.conf: Wine/Proton's NT synchronization primitives.
80 boot.kernelModules = [ "ntsync" ];
81
82 boot.extraModprobeConfig = ''
83 # modprobe.d/nvidia.conf
84 options nvidia NVreg_InitializeSystemMemoryAllocations=0
85 # cachyos-iw-set-regdomain: the Wi-Fi regulatory domain, from the time zone.
86 options cfg80211 ieee80211_regdom="NO"
87 '';
88
89 # --- sysctl.d/70-cachyos-settings.conf --------------------------------------
90
91 boot.kernel.sysctl = {
92 # 150 rather than the file's 100: 30-zram.rules raises it to 150 as soon as
93 # zram is active, which on CachyOS is always.
94 "vm.swappiness" = 150;
95 "vm.vfs_cache_pressure" = 50;
96 "vm.dirty_bytes" = 268435456;
97 "vm.page-cluster" = 0;
98 "vm.dirty_background_bytes" = 67108864;
99 "vm.dirty_writeback_centisecs" = 1500;
100 "kernel.nmi_watchdog" = 0;
101 "kernel.unprivileged_userns_clone" = 1;
102 "kernel.printk" = "3 3 3 3";
103 "kernel.kptr_restrict" = 2;
104 "net.core.netdev_max_backlog" = 4096;
105 "fs.file-max" = 2097152;
106 };
107
108 # --- udev rules ---------------------------------------------------------------
109
110 services.udev.extraRules = ''
111 # 60-ioschedulers.rules
112 ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
113 ACTION=="add|change", KERNEL=="sd[a-z]*|mmcblk[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
114 ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="kyber"
115
116 # 40-hpet-permissions.rules, 99-cpu-dma-latency.rules
117 KERNEL=="rtc0", GROUP="audio"
118 KERNEL=="hpet", GROUP="audio"
119 DEVPATH=="/devices/virtual/misc/cpu_dma_latency", OWNER="root", GROUP="audio", MODE="0660"
120
121 # 50-sata.rules
122 ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_supported}=="1", ATTR{link_power_management_policy}=="*", ATTR{link_power_management_policy}="max_performance"
123
124 # 71-nvidia.rules: runtime power management for the NVIDIA GPU.
125 ACTION=="add|bind", SUBSYSTEM=="pci", DRIVERS=="nvidia", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", TEST=="power/control", ATTR{power/control}="auto"
126 ACTION=="remove|unbind", SUBSYSTEM=="pci", DRIVERS=="nvidia", ATTR{vendor}=="0x10de", ATTR{class}=="0x03[0-9]*", TEST=="power/control", ATTR{power/control}="on"
127 '';
128
129 # --- tmpfiles.d ---------------------------------------------------------------
130
131 systemd.tmpfiles.rules = [
132 # thp.conf, thp-shrinker.conf
133 "w! /sys/kernel/mm/transparent_hugepage/defrag - - - - defer+madvise"
134 "w! /sys/kernel/mm/transparent_hugepage/khugepaged/max_ptes_none - - - - 409"
135 # coredump.conf
136 "e /var/lib/systemd/coredump - - - 3d"
137 ];
138
139 # --- systemd ------------------------------------------------------------------
140
141 # system.conf.d/00-timeout.conf, 10-limits.conf
142 systemd.settings.Manager = {
143 DefaultTimeoutStartSec = "15s";
144 DefaultTimeoutStopSec = "10s";
145 DefaultLimitNOFILE = "2048:2097152";
146 };
147 # user.conf.d/00-timeout.conf, 10-limits.conf
148 systemd.user.settings.Manager = {
149 DefaultTimeoutStartSec = "15s";
150 DefaultTimeoutStopSec = "10s";
151 DefaultLimitNOFILE = "1024:1048576";
152 };
153
154 # journald.conf.d/00-journal-size.conf
155 services.journald.settings.Journal.SystemMaxUse = "50M";
156
157 # timesyncd.conf.d/10-timesyncd.conf
158 services.timesyncd = {
159 servers = [ "time.cloudflare.com" ];
160 fallbackServers = [
161 "time.google.com"
162 "0.nixos.pool.ntp.org"
163 "1.nixos.pool.ntp.org"
164 ];
165 };
166
167 # system/user@.service.d/delegate.conf: lets user services (and ananicy)
168 # manage their own CPU, I/O and memory controllers.
169 systemd.services."user@".serviceConfig.Delegate = "cpu cpuset io memory pids";
170
171 # system/rtkit-daemon.service.d/override.conf
172 security.rtkit.enable = true;
173 systemd.services.rtkit-daemon.serviceConfig.LogLevelMax = "info";
174
175 # systemd-oomd per-slice defaults (system.slice.d, user-.slice.d,
176 # session.slice.d).
177 systemd.oomd.enable = true;
178 systemd.slices = {
179 "system".sliceConfig = {
180 ManagedOOMSwap = "kill";
181 ManagedOOMMemoryPressure = "kill";
182 ManagedOOMMemoryPressureLimit = "80%";
183 };
184 "user-".sliceConfig = {
185 ManagedOOMSwap = "kill";
186 ManagedOOMMemoryPressure = "kill";
187 ManagedOOMMemoryPressureLimit = "80%";
188 };
189 };
190 systemd.user.slices.session.sliceConfig.ManagedOOMPreference = "omit";
191
192 # system/pci-latency.service + /usr/bin/pci-latency
193 systemd.services.pci-latency = {
194 description = "Adjust latency timers for PCI peripherals";
195 wantedBy = [ "multi-user.target" ];
196 serviceConfig.Type = "oneshot";
197 path = [ pkgs.pciutils ];
198 script = ''
199 setpci -v -s '*:*' latency_timer=20
200 setpci -v -s '0:0' latency_timer=0
201 setpci -v -d "*:*:04xx" latency_timer=80
202 '';
203 };
204
205 # security/limits.d/20-audio.conf
206 security.pam.loginLimits = [
207 {
208 domain = "@audio";
209 item = "rtprio";
210 type = "-";
211 value = "99";
212 }
213 {
214 domain = "@audio";
215 item = "nice";
216 type = "-";
217 value = "-11";
218 }
219 ];
220
221 hardware.wirelessRegulatoryDatabase = true;
222
223 # --- CachyOS services ---------------------------------------------------------
224
225 # ananicy-cpp with CachyOS's rules: renices games, compilers, browsers etc.
226 services.ananicy = {
227 enable = true;
228 package = pkgs.ananicy-cpp;
229 rulesProvider = pkgs.ananicy-rules-cachyos;
230 };
231
232 # bpftune: auto-tunes network and other kernel settings (enabled on CachyOS).
233 services.bpftune.enable = true;
234
235 # sched-ext schedulers, as CachyOS's scx-scheds. Off there too (scx_loader was
236 # disabled); to try one:
237 # services.scx = { enable = true; scheduler = "scx_lavd"; };
238
239 # power-profiles-daemon, with the profile you had set on CachyOS.
240 services.power-profiles-daemon.enable = true;
241 # Started with the daemon itself (wanting it from multi-user.target makes an
242 # ordering cycle). Skipped where there is no performance profile, e.g. in a VM.
243 systemd.services.power-profile-performance = {
244 description = "Select the performance power profile";
245 after = [ "power-profiles-daemon.service" ];
246 bindsTo = [ "power-profiles-daemon.service" ];
247 wantedBy = [ "power-profiles-daemon.service" ];
248 serviceConfig.Type = "oneshot";
249 path = [ pkgs.power-profiles-daemon ];
250 script = ''
251 if powerprofilesctl list | grep -q 'performance:'; then
252 powerprofilesctl set performance
253 fi
254 '';
255 };
256
257 environment.systemPackages = [
258 game-performance
259 dlss-swapper
260 ];
261}