Today in Edworking News we want to talk about Linux's Bedtime Routine. How does Linux move from an awake machine to a hibernating one? How does it then manage to restore all state? These questions led me to read way too much C in trying to figure out how this particular hardware/software boundary is navigated. This investigation will be split into a few parts, with the first one going from invocation of hibernation to synchronizing all filesystems to disk. This article has been written using Linux version 6.9.9, the source of which can be found in many places, but can be navigated easily through the Bootlin Elixir Cross-Referencer: https://elixir.bootlin.com/linux/v6.9.9/source. Each code snippet will begin with a link to the above giving the file path and the line number of the beginning of the snippet.
A Starting Point for Investigation: /sys/power/state and /sys/power/disk
These two system files exist to allow debugging of hibernation and thus control the exact state used directly. Writing specific values to the state file controls the exact sleep mode used, and disk controls the specific hibernation mode. This is extremely handy as an entry point to understand how these systems work since we can just follow what happens when they are written to.
Show and Store Functions
These two files are defined using the power_attr macro. The `show` function is called on reads and `store` on writes. The `state_show` function prints all the available sleep states, while `state_store` provides our entry point. If the string “disk” is written to the state file, it calls `hibernate()`, which is our entry point.
Autosleep
Our first detour is into the autosleep system. When checking the state above, you may notice that the kernel grabs the `pm_autosleep_lock` before checking the current state. Autosleep is a mechanism originally from Android that sends the entire system to either suspend or hibernate whenever it is not actively working on anything. This system is implemented as a workqueue that checks the current number of wakeup events, processes, and drivers that need to run. If there aren’t any, then the system is put into the autosleep state, typically suspend. However, it could be hibernate if configured that way via `/sys/power/autosleep`.
The Steps of Hibernation
Hibernation Kernel Config
Most of the hibernate-specific functions do nothing unless you’ve defined `CONFIG_HIBERNATION` in your Kconfig. For instance, `hibernate` itself is defined as the following if `CONFIG_HIBERNATE` is not set.
Check if Hibernation is Available
We begin by confirming that we actually can perform hibernation via the `hibernation_available` function. The `nohibernate` flag is controlled by the kernel command line, set via either `nohibernate` or `hibernate=no`. The `security_locked_down` hook for Linux Security Modules prevents hibernation to an unencrypted storage device. The `secretmem_active` checks whether there is any active use of `memfd_secret`, and if so, it prevents hibernation. The `cxl_mem_active` checks whether any CXL memory is active.
Check Compression
The next check is for whether compression support is enabled, and if so, whether the requested algorithm is enabled. The `nocompress` flag is set via the hibernate command line parameter, setting `hibernate=nocompress`. If compression is enabled, then `hibernate_compressor` is copied to `hib_comp_algo`.
Grab Locks
The next step is to grab the sleep and hibernation locks via `lock_system_sleep` and `hibernate_acquire`. First, `lock_system_sleep` marks the current thread as not freezable, which will be important later. It then grabs the `system_transistion_mutex`, which locks taking snapshots or modifying how they are taken, resuming from a hibernation image, entering any suspend state, or rebooting.
Prepare Console
The kernel next calls `pm_prepare_console`. This function only does anything if `CONFIG_VT_CONSOLE_SLEEP` has been set. This prepares the virtual terminal for a suspend state, switching away to a console used only for the suspend state if needed.
Notify Power Management Call Chain
This will call a chain of power management callbacks, passing first `PM_HIBERNATION_PREPARE` and then `PM_POST_HIBERNATION` on startup or on error with another callback.
Sync Filesystems
The next step is to ensure all filesystems have been synchronized to disk. This is performed via a simple helper function that times how long the full synchronize operation, `ksys_sync`, takes. `ksys_sync` wakes and instructs a set of flusher threads to write out every filesystem, first their inodes, then the full filesystem, and then finally all block devices, to ensure all pages are written out to disk.
The End of Preparation
With that, the system has finished preparations for hibernation. This is a somewhat arbitrary cutoff, but next, the system will begin a full freeze of userspace to then dump memory out to an image and finally to perform hibernation. All this will be covered in future articles!
Image: Representation of Linux Hibernation Process.
Remember these 3 key ideas for your startup:
Understanding System States: Knowing how your system transitions between different states, such as hibernation, can help you optimize power management and performance. This is crucial for startups dealing with mobile or embedded systems.
Security Measures: Implementing security measures like `security_locked_down` and `secretmem_active` ensures that sensitive data is protected during hibernation. This is particularly important for startups handling sensitive information.
Efficient Resource Management: Utilizing features like autosleep can significantly improve resource management, especially for startups focusing on mobile applications. Efficient resource management can lead to better battery life and overall system performance.
Edworking is the best and smartest decision for SMEs and startups to be more productive. Edworking is a FREE superapp of productivity that includes all you need for work powered by AI in the same superapp, connecting Task Management, Docs, Chat, Videocall, and File Management. Save money today by not paying for Slack, Trello, Dropbox, Zoom, and Notion.
For more details, see the original source.