power: stabilize suspend-then-hibernate on P14s G6 AMD
acpi.ec_no_wakeup=1 stops EC interrupts from thrashing s2idle, and a dconf system-db override disables gsd-power's sleep handlers so logind owns all sleep/idle policy (gsd was re-waking before HibernateDelaySec). Split lid/suspend policy by power source (s-t-h on battery, plain suspend on AC), map power key to hibernate, drop HibernateDelaySec to 15min while re-validating thermals, and disable USB-device wakeup via udev.
This commit is contained in:
parent
97d2fd6096
commit
a72fb75811
2 changed files with 37 additions and 7 deletions
|
|
@ -15,6 +15,21 @@
|
||||||
services.displayManager.gdm.enable = true;
|
services.displayManager.gdm.enable = true;
|
||||||
services.desktopManager.gnome.enable = true;
|
services.desktopManager.gnome.enable = true;
|
||||||
|
|
||||||
|
# Let systemd-logind own all sleep/idle policy. gsd-power otherwise
|
||||||
|
# second-guesses suspend-then-hibernate and re-wakes the machine before
|
||||||
|
# HibernateDelaySec elapses (observed on P14s G6 AMD). Set via dconf
|
||||||
|
# system db (gsettings-overrides only compiles desktop/shell/mutter
|
||||||
|
# schemas, so a g-s-d plugin override there is silently dropped).
|
||||||
|
programs.dconf.profiles.user.databases = [{
|
||||||
|
settings = {
|
||||||
|
"org/gnome/settings-daemon/plugins/power" = {
|
||||||
|
sleep-inactive-battery-type = "nothing";
|
||||||
|
sleep-inactive-ac-type = "nothing";
|
||||||
|
power-button-action = "nothing";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
|
||||||
# Configure keymap in X11
|
# Configure keymap in X11
|
||||||
services.xserver.xkb = {
|
services.xserver.xkb = {
|
||||||
layout = "us,ru";
|
layout = "us,ru";
|
||||||
|
|
|
||||||
|
|
@ -6,26 +6,41 @@
|
||||||
# resume_offset = first physical block of /var/swapfile (for hibernate from
|
# resume_offset = first physical block of /var/swapfile (for hibernate from
|
||||||
# an ext4 swapfile on LUKS). Recompute if the swapfile is recreated:
|
# an ext4 swapfile on LUKS). Recompute if the swapfile is recreated:
|
||||||
# sudo filefrag -v /var/swapfile | awk 'NR==4{gsub(/\.\./,""); print $4}'
|
# sudo filefrag -v /var/swapfile | awk 'NR==4{gsub(/\.\./,""); print $4}'
|
||||||
boot.kernelParams = [ "amd_pstate=active" "resume_offset=1769472" ];
|
# 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/
|
||||||
|
boot.kernelParams = [ "amd_pstate=active" "resume_offset=1769472" "acpi.ec_no_wakeup=1" ];
|
||||||
|
|
||||||
# Hibernate / resume from encrypted swapfile on LUKS root.
|
# Hibernate / resume from encrypted swapfile on LUKS root.
|
||||||
# P14s G6 AMD has no S3 (Modern Standby only); this enables
|
# P14s G6 AMD has no S3 (Modern Standby only); this enables
|
||||||
# suspend-then-hibernate so long sleeps drain to disk.
|
# suspend-then-hibernate so long sleeps drain to disk.
|
||||||
boot.resumeDevice = "/dev/mapper/luks-71c97ce7-dd29-4b07-8d2a-8cc3985a65bd";
|
boot.resumeDevice = "/dev/mapper/luks-71c97ce7-dd29-4b07-8d2a-8cc3985a65bd";
|
||||||
|
|
||||||
# systemd-logind: when lid closes / suspend pressed, suspend first;
|
# On battery: suspend-then-hibernate (s2idle then hibernate after
|
||||||
# if still asleep after the delay, hibernate.
|
# HibernateDelaySec). Previously this looped suspend->wake->suspend due
|
||||||
|
# to ACPI EC interrupts, but acpi.ec_no_wakeup=1 (above) plus disabling
|
||||||
|
# gsd-power's sleep handlers (in desktop.nix via dconf) makes it stable.
|
||||||
|
# On AC, plain suspend (s2idle) is fine.
|
||||||
services.logind.settings.Login = {
|
services.logind.settings.Login = {
|
||||||
HandleLidSwitch = "suspend-then-hibernate";
|
HandleLidSwitch = "suspend-then-hibernate";
|
||||||
|
HandleLidSwitchExternalPower = "suspend";
|
||||||
HandleSuspendKey = "suspend-then-hibernate";
|
HandleSuspendKey = "suspend-then-hibernate";
|
||||||
|
HandlePowerKey = "hibernate";
|
||||||
IdleAction = "suspend-then-hibernate";
|
IdleAction = "suspend-then-hibernate";
|
||||||
IdleActionSec = "30min";
|
IdleActionSec = "30min";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Switch to hibernate after this long in s2idle.
|
# s2idle window before transitioning to hibernate. acpi.ec_no_wakeup=1
|
||||||
systemd.sleep.settings.Sleep = {
|
# (above) prevents the prior EC-driven s2idle thrash on this machine.
|
||||||
HibernateDelaySec = "45min";
|
# 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
|
||||||
|
# from s2idle. Only usb_device nodes have power/wakeup; matching on the
|
||||||
|
# devtype avoids "Invalid operator for ATTRS" on udev verification.
|
||||||
|
services.udev.extraRules = ''
|
||||||
|
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{power/wakeup}="disabled"
|
||||||
|
'';
|
||||||
|
|
||||||
# CPU frequency scaling
|
# CPU frequency scaling
|
||||||
powerManagement.cpuFreqGovernor = "powersave";
|
powerManagement.cpuFreqGovernor = "powersave";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue