From b4b293ebfa1845cce01106bba0341e4dba9cdfa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ryan4yin=20=7C=20=E4=BA=8C=E8=8A=B1?= Date: Fri, 16 Oct 2026 00:42:48 +0800 Subject: [PATCH] fix(power): pin the tuned profile per host, cap the VM hosts (#458) Assisted-by: DeepSeek Harness (deepseek-flash) --- hosts/12kingdoms-shoukei/default.nix | 7 +++++-- hosts/idols-ai/default.nix | 5 ++++- lib/genVmHostModule.nix | 8 ++++++++ modules/nixos/desktop/default.nix | 2 +- modules/nixos/desktop/power.nix | 17 ----------------- modules/nixos/power.nix | 23 +++++++++++++++++++++++ 6 files changed, 41 insertions(+), 21 deletions(-) delete mode 100644 modules/nixos/desktop/power.nix create mode 100644 modules/nixos/power.nix diff --git a/hosts/12kingdoms-shoukei/default.nix b/hosts/12kingdoms-shoukei/default.nix index 6b8794ef..834bc138 100644 --- a/hosts/12kingdoms-shoukei/default.nix +++ b/hosts/12kingdoms-shoukei/default.nix @@ -21,8 +21,11 @@ in # disable sunshine for security services.sunshine.enable = lib.mkForce false; - # battery-first: override the profile default - services.tuned.ppdSettings.main.default = lib.mkForce "power-saver"; + # battery-first: pin the low-power profile. apple-cpufreq exposes no EPP or + # platform_profile, so the only thing this changes is cpufreq boost. + services.tuned.recommend = { + powersave = { }; + }; # Laptop joins untrusted networks and is never scraped (see youko's # `offlineHosts`); don't expose :9100, and don't keep the smartctl exporter diff --git a/hosts/idols-ai/default.nix b/hosts/idols-ai/default.nix index 9af9e9ff..fd0bfeda 100644 --- a/hosts/idols-ai/default.nix +++ b/hosts/idols-ai/default.nix @@ -58,7 +58,10 @@ in }; services.sunshine.enable = true; - services.tuned.ppdSettings.main.default = lib.mkForce "performance"; + # desktop PC: keep the CPU pinned to the performance profile + services.tuned.recommend = { + throughput-performance = { }; + }; modules.btrbk.enable = true; diff --git a/lib/genVmHostModule.nix b/lib/genVmHostModule.nix index 66973dc0..d852c451 100644 --- a/lib/genVmHostModule.nix +++ b/lib/genVmHostModule.nix @@ -10,6 +10,14 @@ let ipv4WithMask = "${ipv4}/24"; in { + # Physical machines only: these three always-on mini PCs hold their CPU at + # TuneD's power-saving profile (EPP biased to power, cpufreq boost off). A + # MicroVM guest has no EPP or boost of its own, so it never imports this module. + imports = [ ../modules/nixos/power.nix ]; + services.tuned.recommend = { + powersave = { }; + }; + # supported file systems, so we can mount any removable disks with these filesystems boot.supportedFilesystems = [ "ext4" diff --git a/modules/nixos/desktop/default.nix b/modules/nixos/desktop/default.nix index 049dda93..e03af77a 100644 --- a/modules/nixos/desktop/default.nix +++ b/modules/nixos/desktop/default.nix @@ -1,4 +1,4 @@ { mylib, ... }: { - imports = mylib.scanPaths ./.; + imports = mylib.scanPaths ./. ++ [ ../power.nix ]; } diff --git a/modules/nixos/desktop/power.nix b/modules/nixos/desktop/power.nix deleted file mode 100644 index 646f3620..00000000 --- a/modules/nixos/desktop/power.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ ... }: -{ - # TuneD - Tuning Profile Delivery Mechanism for Linux - # A modern replacement for PPD(power-profiles-daemon) - services.tuned = { - enable = true; - settings.dynamic_tuning = true; - ppdSupport = true; # translation of power-profiles-daemon API calls to TuneD - ppdSettings.main.default = "balanced"; # balanced / performance / power-saver - }; - # DBus service that provides power management support to applications - # Required by `tuned-ppd` for handling power supply changes - services.upower.enable = true; - - services.power-profiles-daemon.enable = false; # conflicts with tuned - services.tlp.enable = false; # conflicts with tuned -} diff --git a/modules/nixos/power.nix b/modules/nixos/power.nix new file mode 100644 index 00000000..6a97622d --- /dev/null +++ b/modules/nixos/power.nix @@ -0,0 +1,23 @@ +{ ... }: +{ + # TuneD - Tuning Profile Delivery Mechanism for Linux + # A modern replacement for PPD(power-profiles-daemon), and the only power manager + # here: nixpkgs' tuned module already disables power-profiles-daemon and fails + # the build if TLP, auto-cpufreq or system76-power is enabled as well. + services.tuned = { + enable = true; + settings.dynamic_tuning = true; + + # Hosts pin their profile with `services.tuned.recommend` (an empty rule + # matches any host): TuneD reads /etc/tuned/recommend.conf in its automatic + # profile mode on every boot. `ppdSettings.main.default` looks like it does + # the same, but never wins -- tuned-ppd restores the base profile it saved in + # /etc/tuned/ppd_base_profile, or TuneD's own recommendation, first. Nothing + # here uses the PPD D-Bus API, so tuned-ppd stays off instead of overwriting + # the pinned profile at startup. + ppdSupport = false; + }; + + # Battery/AC state, used by the desktops; tuned-ppd was the other consumer. + services.upower.enable = true; +}