Waking a Sleeping Desktop: Problem Statement

My Ubuntu desktop cannot use a classic S3 ‘suspend to RAM’, because of limitations of the BIOS. This is most likely because the ASUS motherboard doesn’t support this ACPI suspend type. I need to use shallow suspend (s2idle) at a slightly higher idling power draw, and need the machine to wake up correctly.

Because I live in Ubuntu-land, hardware doesn’t really work like that. Specifically, the GPU actually being used as a graphics card (a GTX 1050 Ti) wasn’t waking.

After fixing the GPU, it was discovered that the network card (an Intel I225‑V Ethernet controller) wasn’t waking up cleanly either.

Suspending and Waking the GPU

Initial GPU problems

When waking, the GTX 1050 Ti would come up in a tangled state: the screen flickered erratically, and the journalctl was flooded with NVRM: Xid 13 (graphics exception) and Xid 31 (MMU fault) errors. These errors occur when the NVIDIA driver’s built‑in VRAM‑restore logic attempts to reload video‑memory state that no longer matches the hardware layout, triggering out‑of‑bounds faults. In response, the driver would forcibly reset the GPU (‘Node Reboot Required’), causing the visible corruption.

Rather than wrestle with patched ACPI tables or unstable firmware hacks, a cleaner workaround was used: a tiny systemd‑sleep hook that unloads all Nvidia modules just before suspend and reloads them immediately after resume. By tearing down the driver state completely, we bypass the faulty VRAM‑restore logic and force a fresh initialisation on wake. The result is a crisp, reliable resume: no more shader header errors, no more black screens, just a desktop that wakes up ready to go.

Script to Fix GPU Wakeup

This script fixed the issue with the GPU not waking up cleanly:

/usr/lib/systemd/system-sleep/nvidia-fix.sh (must be executable)

#!/bin/sh
case "$1" in
  pre)
    echo "Unloading NVIDIA modules before suspend"
    modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia
    ;;
  post)
    echo "Reloading NVIDIA modules after resume"
    modprobe nvidia
    modprobe nvidia_uvm
    modprobe nvidia_modeset
    modprobe nvidia_drm
    ;;
esac

Suspending and Waking the Network Interface Card

Issues with the NIC

After waking from standby, the Intel I225‑V Ethernet controller stayed offline because its igc driver remained in a suspended state, leaving the enp8s0 (wired) network interface down.

To resolve this, I added a lightweight systemd‑sleep hook that unloads the igc kernel module before suspend and reloads it immediately after resume, then brings enp8s0 back up. This ensures the network hardware reinitialises cleanly on wake, restoring wired connectivity without a full reboot.

Previously, the desktop was waking with wifi only.

Script Fixing the NIC

/usr/lib/systemd/system-sleep/igc-fix.sh (must be executable)

#!/bin/sh
case "$1" in
  pre)
    # Unload the Intel network driver before suspend
    modprobe -r igc
    ;;
  post)
    # Reload it and bring the interface back up after resume
    modprobe igc
    # Give it a moment to initialise
    sleep 1
    ip link set enp8s0 up
    ;;
esac

Summary

I have now finally achieved a computer that can be left on suspend overnight, and woken up cleanly in the morning. Graphics output and network connectivity are fully working.