Difference between revisions of "Suspend to RAM"

From ArchWiki
Jump to navigation Jump to search
(double redirect)
(47 intermediate revisions by 13 users not shown)
Line 1: Line 1:
From [[Wikipedia:Sleep mode]]:
#REDIRECT [[Power_management/Suspend_and_hibernate]]
:''Sleep mode can go by many different names, including '''Stand By''', '''Sleep''', and '''Suspend'''. When placed in this sleep mode, aside from the RAM which is required to restore the machine's state, the computer attempts to cut power to all unneeded parts of the machine. Because of the large power savings, most laptops automatically enter this mode when the computer is running on batteries and the lid is closed.''
Suspend to RAM in Arch Linux using one of the following methods:
* [[pm-utils]]
* [[Suspending to RAM with hibernate-script]]
* [[uswsusp]]
= Suspend Framework =
There are three canonical suspend backends - kernel, uswsusp and tuxonice - which instead of being configured or called directly, can be plugged into the suspend framework provided by '''pm-utils'''.
== Backends/Methods ==
=== kernel ===
The first approach is to directly inform the kernel to enter a suspended state; the exact method and state depends on the level of hardware support.
''/usr/lib/pm-utils/pm-functions::294'' (comments added):
if grep -q mem /sys/power/state; then
    # Suspend-to-RAM
    # ACPI State S3
    # Device State D3
    # Greatest power savings, slower resume
    do_suspend() { echo -n "mem" >/sys/power/state; }
elif [ -c /dev/pmu ] && pm-pmu --check; then
    # Suspend using Macintosh-style PMU
    # Fallback for older kernels in which the sysfs interface does not support this hardware
    do_suspend() { pm-pmu --suspend; }
elif grep -q standby /sys/power/state; then
    # Power-On-Suspend
    # ACPI State S1
    # Device State D1 (supported devices)
    # Minimal power savings, fast resume
    do_suspend() { echo -n "standby" >/sys/power/state; }
=== uswsusp ===
While Suspend-to-RAM may generally work, often-times 'hacks' are needed to reinitialize the video card or turn on the backlight. The uswsusp ('Userspace Software Suspend') package provides '''s2ram''', a wrapper around the kernel's suspend-to-RAM mechanism which perform some graphics adapter manipulations from userspace before suspending and after resuming. This includes:
*passing acpi_sleep=s3_bios to the kernel
*passing acpi_sleep=s3_mode to the kernel
*passing both of the above (acpi_sleep=s3_bios,s3_mode) to the kernel
*POSTing the video card from userspace after resume using vbetool
*saving the VBE state before suspend and restoring it after resume using vbetool
This is accomplished by a hardware whitelist maintained by HAL - '''s2ram''' translates the HAL database options into '''s2ram''' parameters.
Since HAL is deprecated and KMS drivers can save the state of the grahic card directly without userspace quirks, '''s2ram''' development is discontinued and no further whitelist entries are accepted. If a KMS driver is in use, '''s2ram''' will directly suspend the machine.
=== tuxonice ===
== Configuration ==
'''pm-utils''' is suspend and powerstate settings framework implementing extensible hooks run in alphanumerical order as root from ''{/usr/lib/pm-utils/,/etc/pm/}{sleep.d/,power.d/}''. The suspend backend is specified by the SLEEP_MODULE configuration variable in ''/etc/pm/config.d'' and defaults to the kernel backend. The Arch Linux package ships with support for the following backends:
pacman -Ql pm-utils | grep module.d
pm-utils /usr/lib/pm-utils/module.d/
pm-utils /usr/lib/pm-utils/module.d/kernel
pm-utils /usr/lib/pm-utils/module.d/tuxonice
pm-utils /usr/lib/pm-utils/module.d/uswsusp
Furthermore, '''pm-utils''' ships with its own video quirks database in ''/usr/lib/pm-utils/video-quirks/''.
However to be able to use the alternative suspend backends - uswsusp or tuxonice - the respective packages need to be installed
*uswsusp - available in [[AUR]] under the name [https://aur.archlinux.org/packages.php?ID=44473 uswsusp-git]
*tuxonice - available in [[AUR]] under the name [https://aur.archlinux.org/packages.php?ID=15224 kernel26-ice]
=== Internals ===
This outlines the internal actions when '''pm-suspend''' is run, describing how '''pm-utils''' gracefully falls back onto the kernel method if the requirements of other methods are not met.
$ pm-suspend
The first step is set-up preliminary variables and source parent scripts:
export STASHNAME=pm-suspend
export METHOD="$(echo ${0##*pm-} |tr - _)"
. "/usr/lib/pm-utils/pm-functions"
The variable ''METHOD'' is extracted from the executable name, ''suspend'' from '''pm-suspend''' and ''hibernate'' from '''pm-hibernate'''.
The location of runtime configuration parameters is defined in ''/usr/lib/pm-utils/pm-functions'' as ''PM_UTILS_RUNDIR="/var/run/pm-utils"'' and ''STORAGEDIR="${PM_UTILS_RUNDIR}/${STASHNAME}/storage"''.  Therefore ''STORAGEDIR="/var/run/pm-utils/pm-suspend/storage"''; this is where pm-suspend will cache its configuration. Disabled hooks are stored as plain text files with the hook name prefixed by "''disable_hook:''". Configuration parameters are appended to the ''parameters'' file:
$  ls -lah /var/run/pm-utils/pm-suspend/storage/
-rw-r--r-- 1 root root  20 May 19 09:57 disable_hook:99video
-rw-r--r-- 1 root root  0 May 19 02:59 parameters
-rw-r--r-- 1 root root 247 May 19 02:59 parameters.rm
-rw-r--r-- 1 root root  9 May 19 02:59 state:cpu0_governor
-rw-r--r-- 1 root root  9 May 19 02:59 state:cpu1_governor
Then ''pm-functions'' will source the files located in ''/etc/pm/config.d/'' in addition to ''/usr/lib/pm-utils/defaults''. Upon returning, ''pm-functions'' will proceed to source the files specified by $SLEEP_METHOD as ''/usr/lib/pm-utils/module.d/$SLEEP_METHOD[...]'' if they exist:
for mod in $SLEEP_MODULE; do
    [ -f "$mod" ] || continue
    . "$mod"
Otherwise, if $SLEEP_MODULE is empty, ''do_suspend()'' will be set to the kernel backend as described above:
if [ -z "$SUSPEND_MODULE" ]; then
    if grep -q mem /sys/power/state; then
        do_suspend() { echo -n "mem" >/sys/power/state; }
    elif [ -c /dev/pmu ] && pm-pmu --check; then
        do_suspend() { pm-pmu --suspend; }
    elif grep -q standby /sys/power/state; then
        do_suspend() { echo -n "standby" >/sys/power/state; }
Assuming $SLEEP_MODULE is not empty and '''uswsusp''' is specified, ''/usr/lib/pm-utils/module.d/uswsusp'' is executed. This script checks several requirements (these are the requirements for being able to use uswsusp):
* command_exists s2ram
* grep -q mem /sys/power/state || ( [ -c /dev/pmu ] && pm-pmu --check; );
If these requirements are met, do_suspend() is defined as:
    s2ram --force $OPTS
Most importantly, the '''uswsusp''' module runs:
add_before_hooks uswsusp_hooks
add_module_help uswsusp_help
The first function, ''add_before_hook'' disables the '''pm-utils''' hooks '''99video''' since this functionality is subsumed by '''s2ram'''.
The second function, ''add_module_help'', adds uswsusp-module-specific help, which in essence replaces the help function provided by '''99video'''.
Back to '''pm-suspend''':
command_exists "check_$METHOD" && command_exists "do_$METHOD"
This verifies that the ''check_suspend'' and ''do_suspend'' methods have been defined. The ''check_suspend'' method simply verifies that $SUSPEND_MODULE is not empty:
check_suspend() { [ -n "$SUSPEND_MODULE" ]; }
Lastly, '''pm-suspend''' must run all hooks that have not been disabled, sync file-system buffers, and run ''do_suspend'':
if run_hooks sleep "$ACTION $METHOD"; then
    # Sleep only if we know how and if a hook did not inhibit us.
    log "$(date): performing $METHOD"
    "do_$METHOD" || r=128
    log "$(date): Awake."
The method ''run_hooks'' is a wrapper for ''_run_hooks'', which the case of pm-suspend is called as ''run_hooks sleep "suspend suspend"''. Given that:
The method ''_run_hooks'', will for each hook in ''"${PM_UTILS_LIBDIR}/$1.d"'' and ''"${PM_UTILS_ETCDIR}/$1.d"'', check that sleep has not been inhibited and update the runtime parameters stored in ''$PARAMETERS'' before running each hook via ''run_hook $hook $2''. In the case of Suspend-to-RAM, all the hooks in ''{/usr/lib/pm-utils/sleep.d/,/etc/pm/sleep.d/}'' will be enumerated, and ''run_hook'' will be passed the parameters ''$hook'' and "''suspend suspend''". The method ''run_hook'' uses the ''hook_ok'' function to verify that the hook has not been disabled before executing the hook with the "''suspend suspend''" parameters.
=== Which of What to Use ===
==== Framework or Not? ====
Directly calling the kernel backend method is significantly faster than calling '''pm-suspend''', since running all the hooks provided by the '''pm-utils''' framework invariable takes time. Even uswsusp is faster than '''pm-suspend'''. However, the recommended approach is to use '''pm-utils''' as it can properly:
* set hardware clock
* restore wireless
* etc...
In fact, only the '''pm-utils''' approach can be called without special privileges, see [[pm-utils#Suspend.2FHibernate as regular user]]
==== Which Backend/Method ====
* kernel -  hooks provided by '''pm-utils''' (including video quirks) with kernel method. Recommended.
* uswsusp - hooks provided by '''pm-utils''' except video99 with '''s2ram''' assuming responsibility for video quirks. Not necessary unless the kernel method explicitly fails to work.
* tuxonice - ...
== Other Resources ==
*[http://www.mjmwired.net/kernel/Documentation/power/states.txt Kernel Power Management Interface]
*[http://www.mjmwired.net/kernel/Documentation/power/interface.txt System Power Management States]
*[http://suspend.sourceforge.net/ Uswsusp Home Page]
*[http://tr.opensuse.org/S2ram OpenSUSE s2ram Documentation]

Latest revision as of 18:37, 21 April 2015