| # Hibernation in powerd |
| |
| ## Introduction |
| |
| Hibernation, also known as suspend-to-disk, or S4, describes a system power |
| state transition wherein RAM is saved to disk and the system is put into a low |
| power state. It can achieve the same fidelity of user state restoration as |
| suspend-to-RAM, but with power consumption closer (and oftentimes identical to) |
| a shut down system. The improved power usage over suspend-to-RAM comes with the |
| tradeoff of disk usage and increased latency. Hibernation can be thought of as a |
| middle ground between suspend and shutdown, taking some attributes from each. |
| |
| ## Powerd's role in hibernation |
| |
| Powerd acts as a policy engine and initiator of hibernate, just as it does for |
| system suspend and shutdown-from-idle transitions. Powerd determines at startup |
| if the system is capable of hibernation. It may initiate a hibernation as part |
| of an explicit SuspendRequest to suspend to disk, or passively as a substitute |
| for shutdown-after-x. |
| |
| All of the documentation for suspend/resume applies to going down for |
| hibernation as well. From the application perspective, to first order there is |
| no detectable difference between the two. Like suspend/resume, powerd emits a |
| `SuspendImminent` signal when the system is going to transition to hibernate, |
| and a `SuspendDone` signal when the resume transition is complete. Users of the |
| `SuspendDone` signal can look at the deepest_state member to determine whether |
| or not a hibernation occurred. |
| |
| The actual mechanics of hibernate are handled by a separate service, [hiberman]. |
| See the hiberman documentation for the gritty details of how the system goes |
| down for and comes up from hibernation. |
| |
| ## Powerd and hibernation resume |
| |
| Resume from hibernation works by first doing a cold boot, then loading the |
| hibernation image from disk and jumping back into it. That means there is a |
| point at which ChromeOS is running, but then the current execution environment |
| abruptly ends as control is returned to the hibernated system. This event is |
| known as a resume from hibernation. |
| |
| Resume from hibernation is initiated and mostly coordinated by hiberman rather |
| than powerd. Powerd still participates in this transition however in terms of |
| emitting the `SuspendImminent` signal and executing suspend dbus callbacks |
| before letting the resume transition proceed. |
| |
| To allow daemons to prepare for an imminent resume from hibernation, powerd |
| sends out the `SuspendImminent` dbus signal, with the action member set to |
| `HIBERNATE_RESUME`. Daemons already registered for `SuspendImminent` signals |
| that are unaware of the action member will end up doing the same thing they |
| would do for a suspend-to-RAM, which almost always ends up being the right |
| behavior anyway. |
| |
| If for some reason the resume transition fails, then the hibernation image is |
| discarded, and this boot continues as if it were a fresh boot. In this case |
| powerd sends out a `SuspendDone` corresponding to the `SuspendImminent` it just |
| sent, hiberman cleans up, and the system proceeds as usual. |
| |
| ### Communication between powerd and hiberman during resume |
| |
| Powerd and hiberman need to coordinate during the resume transition. Hiberman |
| initiates resume early in boot and waits for login credentials to arrive. Once |
| the hibernation image is fully loaded on disk and the resume transition is ready |
| to execute, hiberman asks powerd to send the `SuspendImminent` signal and run |
| suspend callbacks. It does this using a new flavor value to RequestSuspend: |
| `RESUME_FROM_DISK_PREPARE`. This causes powerd to do its callback dbus activity, |
| but not actually initiate any further transition itself. It instead emits a |
| `HibernateResumeReady` signal, which lets hiberman know that resume callbacks |
| have completed. At this point hiberman will trigger the final steps of resume, |
| ending the execution environment upon success. |
| |
| In the abort scenario, hiberman initiates a rollback of the resume within powerd |
| by using yet another new flavor value of `RequestSuspend`: |
| `RESUME_FROM_DISK_ABORT`. Upon receiving this, powerd emits its `SuspendDone` |
| signal corresponding to the `SuspendImminent` it sent out earlier, and resets |
| its state machine back to idle. |
| |
| The period where powerd is braced for an imminent resume from hibernation is |
| meant to be brief, just a few seconds at most. While in this state, other powerd |
| suspend requests are ignored, as only one power state transition is expected to |
| be occurring at a time. |
| |
| The new RequestSuspend flavors (`RESUME_FROM_DISK_PREPARE` and |
| `RESUME_FROM_DISK_ABORT`) as well as the `HibernateResumeReady` signal are meant |
| to be internal communication mechanisms between powerd and hiberman. |
| Applications and other system daemons should not use these mechanisms directly, |
| as they are subject to change without notice. |
| |
| [hiberman]: https://chromium.googlesource.com/chromiumos/platform2/+/HEAD/hiberman |