Linux Suspend Statistics: Attribute the Failed Phase Before Blaming the Wake Source

Read Linux suspend statistics before and after one controlled attempt, then correlate changed phase counters with callback logs. Historical last-failure fields are clues, not a fresh, atomic failure record. A recent wake event does not explain a failure that actually occurred while freezing tasks, preparing a device, or restoring it during unwind.

Applicability: this article pins Linux v6.12 /sys/power/suspend_stats and its implementation. The counter example is hypothetical. No suspend attempt, fault injection, or kernel test mode was executed. Attribute availability and platform hardware-sleep reporting must be checked on the target build.

A hypothetical late suspend failure followed by a resume failure increments one overall failure and two phase counters; separate history fields require trace correlation.
Original hypothetical accounting example. Numbers are illustrative, and neither parser tests nor target suspend/fault-injection trials were executed.

1. Capture a baseline with an attempt identifier

Save success, fail, every available failed-phase counter, and last_failed_dev, last_failed_errno, and last_failed_step. Record read errors and missing files rather than substituting zero. Keep the kernel build, boot identity, requested sleep mode, and current test configuration beside the values.

The v6.12 sysfs ABI description defines overall success/failure counts and separate freeze, prepare, suspend, late/noirq suspend, and resume-phase failures. These are accumulated observations, not per-request fields that automatically begin empty.

Use the normal power manager to run one authorized, recoverable development attempt. Capture the command or API result and trace window, then read the same attributes after return. Keep another automatic sleep attempt from silently entering the measurement window through an agreed test setup.

A reboot changes the accounting context. If boot identity changes or counters unexpectedly decrease, stop subtracting them as though they belong to one continuous baseline. Preserve the restart evidence and establish a new baseline.

2. Use deltas to choose the next investigation

A changed failed_freeze count directs attention to task-freezing evidence. A prepare change directs attention to preparation callbacks and their logs. Suspend, suspend_late, and suspend_noirq changes identify different resource and execution contexts. Resume-phase changes describe restoration failures, including restoration after an aborted entry.

These counters narrow the search; they do not explain the failing device’s underlying electrical or software defect. For example, a late-phase failure can be a reported device error or another condition handled by that phase. Read the actual trace before assigning a cause.

Keep wake attribution as a separate evidence column. An IRQ observed near the attempt may have caused an abort, followed a device failure, or occurred during recovery. Phase accounting and event chronology must agree before naming it as the reason.

3. Do not assemble the last fields into an imaginary tuple

The v6.12 implementation advances device, errno, and step histories independently. Their last indexes are not one shared transaction identifier. Reading three neighboring sysfs files therefore does not prove that all three values describe the same failure.

dpm_save_errno increments success for a zero result without clearing the earlier last-failure histories. A successful attempt can leave an old device name, old errno, and old phase visible. Without baseline deltas, a monitoring script can falsely report that an already-resolved failure happened again.

Some failures do not update every history. In the exact device preparation path, an unrecoverable prepare error is logged and its phase recorded, but that path does not add the device through dpm_save_failed_dev. The visible last_failed_dev can consequently remain from an older callback failure.

Even within one attempt, later recovery errors can become the most recent device or phase. Preserve the original entry error and subsequent unwind errors separately. The latest observed phase is not necessarily the first causal failure.

4. Work a two-error attempt

Suppose a hypothetical baseline has fail=3, failed_suspend_late=1, and failed_resume=0. During the next attempt, device A fails late suspend. While earlier completed work is unwound, device B reports a resume failure.

A compatible after-snapshot is fail=4, failed_suspend_late=2, and failed_resume=1. One overall failed attempt produced changes in two phase counters. The last step may now be resume and the last recorded device B, while the overall entry error came from the earlier failure.

The correct report retains both: A prevented the transition, and B failed during recovery. It does not replace A with B as the sole cause, and it does not count two separate suspend attempts merely because two phase counters increased.

Use callback entry/exit and error messages to bind devices to phases. With asynchronous device PM, multiple callbacks may overlap or report errors. A short “last device” string cannot reconstruct that chronology by itself.

5. Interpret overall success at its implementation boundary

In v6.12 pm_suspend(), supported-state processing calls enter_state and passes its returned error to dpm_save_errno. An invalid state rejected before that processing is not necessarily represented as a new counted attempt.

Do not elevate a success increment into proof of physical residency or healthy service from every peripheral. Test modes can deliberately return before a complete platform sleep, and device resume-phase errors are recorded separately from the top-level entry result. Record test mode and inspect changed resume counters even when the overall call reports success.

Hardware-sleep time attributes have their own provider and visibility conditions in the implementation. Missing hardware timing is not zero residency. Use platform-supported residency evidence when the question is whether the intended physical state was reached.

6. Build a reproducible classification fixture

Propose synthetic before/after records for a clean attempt, one late failure, late failure plus resume failure, a successful attempt with stale last fields, and a prepare failure with an older last device. Verify that the report preserves uncertainty instead of inventing associations. These parser fixtures have not been executed here.

For target qualification, use reviewed fault hooks on safe development hardware and retain independent recovery access. Inject one callback failure at a time before attempting combined recovery faults. Preserve raw snapshots and logs before producing a concise classification.

After an aborted attempt, require useful I/O from affected devices and a subsequent clean transition where supported. Correctly reporting the failed phase is only diagnosis; it does not establish that rollback left the product functional.

7. Hand off evidence with explicit linkage

The release package should contain attempt identity, baseline and after values, counter deltas, return status, trace chronology, and unresolved field associations. Label each device-to-error link as trace-supported or unknown.

This turns suspend_stats into a practical search aid while preserving its limits. Investigate the changed phase first, then establish its cause. Do not blame the last wake source or last device merely because its name remains visible after the attempt.

Similar Posts