power: drop the disk swapfile and hibernate
Remove the 58 GiB swapfile on the LUKS root, along with what depended on it: resumeDevice, resume_offset, the suspend-then-hibernate logind actions and HibernateDelaySec. zram is now the only swap, capped at 8 GiB so it can't cut into memory needed for large LLM/GTT loads. Lid, idle and the suspend key now do plain s2idle suspend; the power key powers off. This loses the hibernate fallback that used to end a spurious-wake loop; acpi.ec_no_wakeup=1 and the gsd-power tweaks are now all that keeps s2idle stable. Assisted-by: Claude:opus-5-5
This commit is contained in:
parent
8f0062a5b0
commit
4fb583cf54
2 changed files with 19 additions and 36 deletions
|
|
@ -40,11 +40,8 @@
|
||||||
options = [ "nofail" ];
|
options = [ "nofail" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Encrypted swapfile on LUKS root, sized for hibernate (RAM + headroom).
|
# No disk swap: zram only (modules/power.nix). Hibernate disabled.
|
||||||
# NixOS auto-creates the file and computes resume offset on activation.
|
swapDevices = [ ];
|
||||||
swapDevices = [
|
|
||||||
{ device = "/var/swapfile"; size = 59392; } # 58 GiB, RAM is 54 GiB
|
|
||||||
];
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
|
|
||||||
|
|
@ -3,55 +3,41 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
# AMD P-State driver (active mode for full EPP control)
|
# AMD P-State driver (active mode for full EPP control)
|
||||||
# resume_offset = first physical block of /var/swapfile (for hibernate from
|
|
||||||
# an ext4 swapfile on LUKS). Recompute if the swapfile is recreated:
|
|
||||||
# sudo filefrag -v /var/swapfile | awk 'NR==4{gsub(/\.\./,""); print $4}'
|
|
||||||
# acpi.ec_no_wakeup=1: prevents EC wakeups from draining battery in s2idle
|
# acpi.ec_no_wakeup=1: prevents EC wakeups from draining battery in s2idle
|
||||||
# on P14s G6 AMD. See https://lore.kernel.org/all/ZnFYpWHJ5Ml724Nv@ohnotp/
|
# on P14s G6 AMD. See https://lore.kernel.org/all/ZnFYpWHJ5Ml724Nv@ohnotp/
|
||||||
boot.kernelParams = [ "amd_pstate=active" "resume_offset=133797888" "acpi.ec_no_wakeup=1" ];
|
boot.kernelParams = [ "amd_pstate=active" "acpi.ec_no_wakeup=1" ];
|
||||||
|
|
||||||
# Allow manual fan control via /proc/acpi/ibm/fan (level 0-7, auto,
|
# Allow manual fan control via /proc/acpi/ibm/fan (level 0-7, auto,
|
||||||
# full-speed). Firmware stays in charge while level is "auto".
|
# full-speed). Firmware stays in charge while level is "auto".
|
||||||
boot.extraModprobeConfig = "options thinkpad_acpi fan_control=1";
|
boot.extraModprobeConfig = "options thinkpad_acpi fan_control=1";
|
||||||
|
|
||||||
# Hibernate / resume from encrypted swapfile on LUKS root.
|
# Hibernate disabled: the disk swapfile was removed (it was the resume
|
||||||
# P14s G6 AMD has no S3 (Modern Standby only); this enables
|
# target). To restore: re-add swapDevices, boot.resumeDevice,
|
||||||
# suspend-then-hibernate so long sleeps drain to disk.
|
# resume_offset (filefrag -v /var/swapfile) and the *-hibernate actions.
|
||||||
boot.resumeDevice = "/dev/mapper/luks-71c97ce7-dd29-4b07-8d2a-8cc3985a65bd";
|
|
||||||
|
|
||||||
# zram ahead of the disk swapfile: when a large LLM load pins 20-30 GiB of
|
# zram only, capped at 8 GiB so it can't eat into memory needed for large
|
||||||
# GTT, evicted app pages compress into RAM instead of contending with model
|
# LLM/GTT loads. memoryMax caps the 50% default (~30 GiB).
|
||||||
# reads on the same NVMe (this contention caused 8-minute model loads).
|
|
||||||
# Hibernate is unaffected: the image goes to resumeDevice/resume_offset
|
|
||||||
# (the swapfile), which stays available as overflow swap at priority -2.
|
|
||||||
zramSwap = {
|
zramSwap = {
|
||||||
enable = true;
|
enable = true;
|
||||||
memoryPercent = 50;
|
memoryPercent = 50;
|
||||||
|
memoryMax = 8 * 1024 * 1024 * 1024;
|
||||||
priority = 100;
|
priority = 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
# On battery: suspend-then-hibernate (s2idle then hibernate after
|
# Without swap, hibernate is unavailable: plain s2idle suspend everywhere.
|
||||||
# HibernateDelaySec). Previously this looped suspend->wake->suspend due
|
# Caveat: plain suspend once let a spurious-wake loop run for 1.5 days on
|
||||||
# to ACPI EC interrupts, but acpi.ec_no_wakeup=1 (above) plus disabling
|
# AC (logind re-suspends every 30s with the lid closed); there's no longer
|
||||||
# gsd-power's sleep handlers (in desktop.nix via dconf) makes it stable.
|
# a hibernate fallback to end it. acpi.ec_no_wakeup=1 + gsd-power dconf
|
||||||
# On AC too: plain suspend let a spurious-wake loop run unbounded for 1.5
|
# tweaks (desktop.nix) are what keep s2idle stable.
|
||||||
# days (logind re-suspends every 30s while the lid is closed); with
|
|
||||||
# suspend-then-hibernate it ends in hibernate after HibernateDelaySec.
|
|
||||||
services.logind.settings.Login = {
|
services.logind.settings.Login = {
|
||||||
HandleLidSwitch = "suspend-then-hibernate";
|
HandleLidSwitch = "suspend";
|
||||||
HandleLidSwitchExternalPower = "suspend-then-hibernate";
|
HandleLidSwitchExternalPower = "suspend";
|
||||||
HandleSuspendKey = "suspend-then-hibernate";
|
HandleSuspendKey = "suspend";
|
||||||
HandlePowerKey = "hibernate";
|
HandlePowerKey = "poweroff";
|
||||||
IdleAction = "suspend-then-hibernate";
|
IdleAction = "suspend";
|
||||||
IdleActionSec = "30min";
|
IdleActionSec = "30min";
|
||||||
};
|
};
|
||||||
|
|
||||||
# s2idle window before transitioning to hibernate. acpi.ec_no_wakeup=1
|
|
||||||
# (above) prevents the prior EC-driven s2idle thrash on this machine.
|
|
||||||
# Conservative value while bag-thermal behavior is being re-validated;
|
|
||||||
# raise to 30-45min once confirmed safe.
|
|
||||||
systemd.sleep.settings.Sleep.HibernateDelaySec = "15min";
|
|
||||||
|
|
||||||
# Stop USB devices (e.g. Aerox 3 WL receiver) from waking the machine
|
# Stop USB devices (e.g. Aerox 3 WL receiver) from waking the machine
|
||||||
# from s2idle. Only usb_device nodes have power/wakeup; matching on the
|
# from s2idle. Only usb_device nodes have power/wakeup; matching on the
|
||||||
# devtype avoids "Invalid operator for ATTRS" on udev verification.
|
# devtype avoids "Invalid operator for ATTRS" on udev verification.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue