FreeBSD ACPI Suspend and Resume: Test Hardware, Capture Failures, Recover Safely
Test FreeBSD ACPI sleep states with console safeguards, supported-state checks, suspend-bounce diagnostics, driver isolation, and post-resume validation.
ACPI suspend and resume is a coordination problem across firmware, CPU state, graphics, USB, storage, network, and device drivers. A laptop can advertise a sleep state that does not work reliably with its current firmware or drivers. FreeBSD’s Handbook explicitly cautions that suspend/resume works only on some systems and that graphics and other devices can affect the result.
Treat each test as a controlled hardware experiment. Save work, ensure that you have a recoverable console path, change one variable at a time, and record both the sleep transition and behavior after resume. Do not assume that a successful command means the laptop can safely sleep every time.
Establish the supported states and recovery path
Before testing, identify the FreeBSD release, hardware, firmware version, graphics driver, USB devices, and whether the system is local or remote. A suspend test on a remote-only host can make the machine unreachable with no safe way to resume it.
Check the state list reported by ACPI:
sysctl hw.acpi.supported_sleep_state
sysctl hw.acpi
dmesg | grep -i acpi
This reports firmware and driver information visible to FreeBSD, not a guarantee that every listed state works. The acpiconf utility recognizes several state numbers, but actual support depends on the BIOS implementation and ACPI machine language tables. The Handbook documents S3 as suspend to RAM and notes that S4 hibernation is not supported in its current procedure. Do not configure a state based only on its presence in sysctl output.
Save all work, stop long-running writes, detach external storage safely, and close applications that cannot recover from device resets. For a server, coordinate an approved outage and provide out-of-band management. For a laptop, keep power attached if appropriate, ensure battery charge, and test with a local keyboard or serial console if available.
Run a reversible diagnostic cycle
First test the driver’s suspend and resume paths without actually entering S3. The current FreeBSD Handbook no longer documents debug.acpi.suspend_bounce, but the FreeBSD 15.1 kernel source still defines that debug sysctl. Check that the target release exposes it before running this optional diagnostic:
sysctl debug.bootverbose=1
sysctl debug.acpi.suspend_bounce=1
acpiconf -s 3
When available, suspend_bounce emulates a driver suspend/resume cycle without actually entering S3. This can surface a driver watchdog or firmware-state problem, but it is not equivalent to real sleep because devices may not lose power. Disable the diagnostic settings after collecting output and do not treat a successful bounce as proof that a full suspend works:
sysctl debug.acpi.suspend_bounce=0
sysctl debug.bootverbose=0
When ready for a real S3 test, record current uptime, active network state, battery state, and logs, then run:
acpiconf -s 3
This may suspend the machine and return only after resume. Use it from a local console or a tested management path. If the machine fails to resume, repeated blind key presses or forced power cycles can lose data. Wait for the documented hardware wake gesture, check power and display indicators, and follow the platform recovery procedure before forcing shutdown.
Validate more than the display
After a successful wake, verify that the system resumed rather than rebooted:
uptime
dmesg | tail -150
date
ifconfig -a
netstat -rn
mount
Check system clock, disks and mounted filesystems, network address and route, audio, USB, keyboard, touchpad, graphics, and any external display. A login prompt appearing is insufficient if a service or interface remained wedged. Inspect service logs and perform a real application-level health check.
Perform multiple cycles with a documented interval and device set. One successful transition is weak evidence for repeatability. Test a baseline with external devices removed, then add a dock, USB device, or display one at a time. This isolates which driver or firmware interaction changes the outcome.
Diagnose failed entry and failed resume
If the system does not enter sleep, inspect console output and dmesg for a device that refused suspend, a pending request, or an ACPI method error. Confirm that the chosen sleep state matches hardware support. Turn on bootverbose before reproducing if additional ACPI detail is needed.
If the display stays black after wake, do not immediately assume the machine is powered off. Check keyboard indicators, network reachability, serial console output, and disk activity. A graphics driver may be stuck while the kernel resumed. The Handbook notes that graphics drivers must be loaded for suspend/resume functionality and that non-KMS graphics may require sc(4); follow current graphics driver documentation for the hardware.
If a driver times out or repeats recovery messages, preserve the log and isolate it. Unload as many optional devices or modules as is safe, repeat the test, then add one device class back at a time. Do not unload storage, console, or boot-critical drivers on a production host. Disable Bluetooth or disconnect USB only as a controlled test variable, not as a permanent fix without understanding the operational tradeoff.
If a network connection fails after resume, inspect interface and route state before restarting the whole networking stack. DHCP renewal may be necessary on some links, but a blanket service restart can hide a driver defect. Record whether the interface disappeared, lost carrier, retained its address, or retained the route.
Storage and input failures deserve particular caution. A missing external disk after wake may reflect a USB re-enumeration issue, not a filesystem problem; do not run fsck on a device that has not been identified and safely detached. A keyboard that wakes the machine but then stops responding can leave the system running with no local control. Preserve an alternate console or remote recovery path before enabling automatic sleep on a machine that hosts important services.
Decide on lid-close and resume hooks carefully
FreeBSD can configure lid behavior through the hw.acpi.lid_switch_state sysctl documented by the Handbook. Validate the exact supported state on the target hardware before persisting it. Do not make lid-close sleep the default until open/close tests are reliable and the laptop will not be placed in a bag while still awake.
acpiconf(8) documents executable /etc/rc.suspend and /etc/rc.resume hooks invoked by devd or apmd around sleep transitions. Those hooks can call rcorder scripts marked with the suspend or resume keyword. Keep hooks short, idempotent, and observable. Avoid long network operations or destructive cleanup in a callback that can delay recovery.
If a resume hook is needed, test it independently and ensure it does not assume that network, storage, or display devices have already returned. Log the transition with timestamps and handle missing services gracefully. Do not put a one-off local workaround into shared system scripts until its behavior and rollback are documented.
Firmware and driver isolation
Compare behavior with the same FreeBSD release and firmware on a clean boot, then with only the minimum required devices. Check firmware configuration for sleep state options, USB wake, graphics mode, and ACPI updates; change one item at a time and retain a way to restore original settings.
Binary graphics drivers, USB devices, and device firmware can behave differently across releases. Do not assume a Linux suspend result proves FreeBSD compatibility, but it can help distinguish a hardware/firmware limitation from an OS-specific driver path. Record precise reproducer steps, hardware identifiers, kernel messages, and whether the suspend-bounce test differs from actual S3.
Do not disable ACPI as a generic solution. ACPI supports many core hardware interactions, and disabling it can change interrupt routing, power management, thermal control, and device configuration. Use that only as a narrowly controlled diagnostic under platform-specific guidance.
Use a test matrix rather than a collection of undocumented tweaks. Record release and kernel, firmware settings, ACPI state list, devices attached, whether suspend-bounce passed, whether actual S3 passed, and which functions recovered. Repeat the baseline after each single change. When a kernel update appears to fix a regression, repeat the same device set and cycle count rather than attributing improvement to one unrelated firmware change.
Acceptance and rollback
A stable configuration must pass repeated suspend/resume cycles, preserve filesystems and clock correctness, restore network and input devices, and leave no recurring driver errors. Record firmware settings, loaded drivers, external hardware, sleep state, test count, and failure rate.
If a test breaks the machine, revert the one setting changed, reboot only when safe, and verify filesystem and service health before resuming ordinary work. Keep suspend disabled on critical systems if there is no reliable recovery path. Reliability is more important than an automatic sleep policy that is only intermittently functional.
Related:
- FreeBSD CPU Power Management: Driver-Aware Frequency Tuning in Production
- FreeBSD Host Serial Console: Boot Output, Login, and Recovery
Sources: