Commit Graph
2 Commits
Author SHA1 Message Date
ahmza 67bafd4f73 switch to open nvidia modules and make sleep transitions actually work
three related changes, all needed together to get this card through a
sleep cycle with its framebuffer intact.

open = true. mandatory to set explicitly on driver >= 560, where the
option defaults to null and nixpkgs asserts against null. true because
every card this module targets is turing or later, which is what upstream
recommends open modules for. mkDefault so a future pre-turing host can
override at host level - and note that without it, importing both
gpuNvidia and gpuNvidiaPrime would be an outright merge conflict rather
than something resolvable. this selects between two real builds of the
same release, nvidia-open vs the proprietary kernel modules; it has no
effect on driver version. confirmed after reboot:
/proc/driver/nvidia/version reports the open module.

kernelSuspendNotifier = false. nixpkgs defaults this to
`useOpenModules && version >= 595`, which is silently true here, and that
path wedges the gpu on resume - nv_pm_notifier warns, the card never
comes back, and an unrecoverable gsp rpc storm follows. pinning it false
selects the nvidia-{suspend,hibernate,resume}.service path instead.

installing upstream's system-sleep hook, because those units are wired
only to systemd-{suspend,hibernate}.service, while suspend-then-hibernate
runs as a single systemd-suspend-then-hibernate.service that performs
both transitions internally. no nvidia unit fires for it at all - the
units cannot express it, which is exactly why nvidia ships the hook.
nixpkgs sets systemd.packages from the driver package, but that only
collects lib/systemd/system/, never lib/systemd/system-sleep/, so the
hook is silently discarded.

it cannot be installed verbatim, for two separate reasons.

first, past its suspend-then-hibernate branch it ends in an
unconditional `case "$1" in post) nvidia-sleep.sh resume`. for plain
suspend that duplicates nvidia-resume.service, and destructively:
nvidia-sleep.sh's RestoreVT reads /run/nvidia-sleep/Xorg.vt_number,
deletes it, then chvt's back. chvt lives in pkgs.kbd, which nixpkgs puts
on nvidia-resume.service's path but which is absent from the stripped
path systemd-sleep gives its hooks. the hook would consume the vt file,
fail to chvt, and the real unit would then find nothing to restore.

second, its suspend-then-hibernate dispatch handles post:*,
pre:hibernate and pre:suspend-after-failed-hibernate - but there is no
pre:suspend, which is the *first* leg of suspend-then-hibernate. it
matched nothing, fell through, and the driver never got its vram-spool
handshake, so with NVreg_PreserveVideoMemoryAllocations=1 the gpu refused
to suspend and the whole operation aborted:

  nvidia 0000:2d:00.0: PM: failed to suspend async: error -5
  PM: Some devices failed to suspend, or early wake event detected
  systemd-sleep: Failed to put system to sleep. System resumed again:
    Input/output error

so the wrapper gates out everything except suspend-then-hibernate, fills
in pre:suspend the same way upstream fills in pre:hibernate, and hands
the rest to upstream unchanged. worth reporting upstream - as shipped
that hook cannot work for suspend-then-hibernate whenever
PreserveVideoMemoryAllocations is on.

verified on hardware: plain suspend and plain hibernate both clean with
no chvt failure and the vt file consumed by the right unit, and a full
suspend-then-hibernate cycle now runs all four transitions - suspend
entry (deep), rtc wake, hibernation entry, hibernation exit.
2026-08-06 17:08:55 +01:00
ahmza dda5d14d63 initial commit 2026-08-05 18:57:23 +01:00