Difference between revisions of "Power management"

From ArchWiki
Jump to: navigation, search
(22 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
[[Category:Power management]]
 
[[Category:Power management]]
{{Stub|The purpose of this article currently overlaps other introductions like [[General Recommendations#Power management]] and [[Laptop#Power Management]]; application-specific information must be moved to the respective articles; only a generic introduction to power management in Arch and to related articles should stay here.}}
+
[[es:Power Management]]
The aim of this page is to try to gather all the informations which are available on the topic of linux power management features. There are several places where one can change power management settings:
+
[[zh-CN:Power Management]]
* Kernel command line parameters in the boot loader
+
{{Article summary start}}
 +
{{Article summary text|Describes power management in Arch Linux.}}
 +
{{Article summary heading|Related}}
 +
{{Article summary wiki|Power saving}}
 +
{{Article summary wiki|Display Power Management Signaling}}
 +
{{Article summary wiki|Suspend and Hibernate}}
 +
{{Article summary end}}
 +
The purpose of this page is to provide general overview of power management in Arch Linux. As Arch Linux uses [[systemd]] as system manager, this article focuses on it.
 +
 
 +
There are multiple places where one can change power management settings:
 +
* [[Kernel parameters]]
 +
* [[Kernel modules]]
 +
* [[udev]] rules
 +
 
 +
There are also many power management tools:
 
* [[systemd]]
 
* [[systemd]]
* Settings by [[pm-utils]]
+
* [[pm-utils]]
* {{pkg|Upower}}
+
 
* [[Laptop Mode Tools]]
 
* [[Laptop Mode Tools]]
Power settings you set in one place could be overwritten in another place.
+
* [[TLP]]
 +
* [[acpid]]
  
==Power saving==
+
{{Note|Power settings you set in one place/tool could be overwritten in another place/tool.}}
See [[power saving]].
+
  
== Where To Change Power Settings ==
+
== Power management with systemd ==
One can pass a kernel command line parameter in the boot loader to activate power management features in certain kernel modules. If you are using systemd you can change some power management options in systemd config files or execute your own config file. pm-utils and upower are working together. pm-utils is responsible for changing the power management options while upower informs pm-utils about system changes. For example if you unplug your laptop from AC upower will signal to pm-utils that the laptop is running on battery. This will cause pm-utils to change some power management options according to its config files.
+
  
Have a look at the [[:Category:Power management|power management category]] to get an overview on what power management options exists in Archlinux:.
+
=== ACPI events ===
  
== Kernel Command Line Parameters ==
+
''systemd'' handles some power-related [[Wikipedia:Advanced_Configuration_and_Power_Interface|ACPI]] events. They can be configured via the following options from {{ic|/etc/systemd/logind.conf}}:
Append the lines to your kernel command line parameter to enable these options. If you change settings for kernel modules make sure they are either compiled into your initrd (insert module name in MODULES in /etc/mkinitcpio.conf) or pass an option via a modprobe config file ([[Kernel_modules#Using_files_in_.2Fetc.2Fmodprobe.d.2F]]).
+
  
=== PCI-e ASPM ===
+
* {{ic|HandlePowerKey}}: specifies which action is invoked when the power key is pressed.
  pcie_aspm=force
+
* {{ic|HandleSuspendKey}}: specifies which action is invoked when the suspend key is pressed.
 +
* {{ic|HandleHibernateKey}}: specifies which action is invoked when the hibernate key is pressed.
 +
* {{ic|HandleLidSwitch}}: specifies which action is invoked when the lid is closed.
  
=== Disable NMI Watchdog ===
+
The specified action can be one of {{ic|ignore}}, {{ic|poweroff}}, {{ic|reboot}}, {{ic|halt}}, {{ic|suspend}}, {{ic|hibernate}}, {{ic|hybrid-sleep}}, {{ic|lock}} or {{ic|kexec}}.
  nmi_watchdog=0
+
  
=== Enable RC6 Power Save Options ===
+
If these options are not configured, ''systemd'' will use its defaults: {{ic|1=HandlePowerKey=poweroff}}, {{ic|1=HandleSuspendKey=suspend}}, {{ic|1=HandleHibernateKey=hibernate}}, and {{ic|1=HandleLidSwitch=suspend}}.
  i915_enable_rc6=#Nr
+
Where ''#Nr'':
+
* '''1''': enable rc6
+
* '''3''': enable rc6 and deep rc6
+
* '''5''': enable rc6 and deepest rc6
+
* '''7''': enable rc6, deep and deepest rc6
+
  
=== Activate Power Save For Intel HD Audio ===
+
On systems which run no graphical setup or only a simple window manager like [[i3]] or [[awesome]], this may replace the [[acpid]] daemon which is usually used to react to these ACPI events.
  snd_hda_intel.power_save=1
+
  
=== Change Usbcore Autosuspend Time ===
+
{{Note|
  usbcore.autosuspend=<time in seconds>
+
* Run {{ic|systemctl restart systemd-logind}} for your changes to take effect.
 +
* ''systemd'' cannot handle AC and Battery ACPI events, so if you use [[Laptop Mode Tools]] or other similar tools [[acpid]] is still required.
 +
}}
  
== pm-utils Settings ==
+
In the current version of ''systemd'', the {{ic|Handle*}} options will apply throughout the system unless they are "inhibited" (temporarily turned off) by a program, such as a power manager inside a desktop environment. If these inhibits are not taken, you can end up with a situation where ''systemd'' suspends your system, then when it wakes up the other power manager suspends it again.
The pm-utils (see also: [[Pm-utils#Power_saving]]) package provides quirks for suspend to RAM and suspend to disk but also includes some scripts for power management. You need upower which registers power changes and signals that information to pm-utils.
+
  
=== Enable SATA Link Power Management ===
+
{{Warning|Currently, the power managers in the newest versions of [[KDE]] and [[GNOME]] are the only ones that issue the necessary "inhibited" commands. Until the others do, you will need to set the {{ic|Handle}} options to {{ic|ignore}} if you want your ACPI events to be handled by [[Xfce]], [[acpid]] or other programs.}}
Execute the following command to enable SATA link power management when on battery:
+
  # echo SATA_ALPM_ENABLE=true > /etc/pm/config.d/sata_alpm
+
  
=== Scripts For Pm-utils Which Enable Power Management Options ===
+
=== Suspend and hibernate ===
These scripts have to be made executable via
+
  # chmod +x <script file>
+
  
==== Enable Runtime PM for PCI Devices ====
+
''systemd'' provides commands for suspend to RAM, hibernate and a hybrid suspend using the kernel's native suspend/resume functionality. There are also mechanisms to add hooks to customize pre- and post-suspend actions.
{{Hc|head=/etc/pm/power.d/device_pm|output=
+
<nowiki>#!/bin/sh
+
  
device_pm() {
+
{{Note|''systemd'' can also use other suspend backends (such as [[Uswsusp]] or [[TuxOnIce]]), in addition to the default ''kernel'' backend, in order to put the computer to sleep or hibernate. See [[Uswsusp#With systemd]] for an example.}}
    for dpcontrol in /sys/bus/{pci,spi,i2c}/devices/*/power/control; do
+
        [ -w "$dpcontrol" ] || continue
+
        echo $1 > "$dpcontrol"
+
    done
+
}
+
  
case "$1" in
+
{{ic|systemctl suspend}} should work out of the box, for {{ic|systemctl hibernate}} to work on your system you need to follow the instructions at [[Suspend and Hibernate#Hibernation]].
    true)
+
        echo "**device power management ON"
+
        device_pm auto
+
        ;;
+
    false)
+
        echo "**device power management OFF"
+
        device_pm on
+
        ;;
+
esac
+
  
exit 0</nowiki>}}
+
=== Sleep hooks ===
  
==== Enable Power Management For USB Devices ====
+
''systemd'' does not use [[pm-utils]] to put the machine to sleep when using {{ic|systemctl suspend}}, {{ic|systemctl hibernate}} or {{ic|systemctl hybrid-sleep}}; ''pm-utils'' hooks, including any [[Pm-utils#Creating_your_own_hooks|custom hooks]], will not be run. However, ''systemd'' provides two similar mechanisms to run custom scripts on these events.
{{Hc|head=/etc/pm/power.d/usb_pm|output=
+
#!/bin/sh
+
case "$1" in
+
    true)
+
      # USB powersaving
+
        for i in /sys/bus/usb/devices/*/power/autosuspend; do
+
            echo 1 > $i
+
        done
+
        for i in /sys/bus/usb/devices/*/power/control; do
+
            echo auto > $i
+
        done
+
sysctl kernel.nmi_watchdog=0
+
    ;;
+
    false)
+
        for i in /sys/bus/usb/devices/*/power/autosuspend; do
+
            echo 2 > $i
+
        done
+
        for i in /sys/bus/usb/devices/*/power/control; do
+
            echo on > $i
+
        done
+
sysctl kernel.nmi_watchdog=1
+
    ;;
+
esac
+
  
exit 0}}
+
==== Suspend/resume service files ====
  
==== Increase VM Writeback Timeout ====
+
Service files can be hooked into ''suspend.target'', ''hibernate.target'' and ''sleep.target'' to execute actions before or after suspend/hibernate. Separate files should be created for user actions and root/system actions.  To activate the user service files run {{ic|systemctl enable suspend@''user'' && systemctl enable resume@''user''}}. Examples:
{{Hc|head=/etc/pm/power.d/vm-writeback|output=
+
<nowiki>#!/bin/sh
+
  
# VM writeback timeout power savings
+
{{hc|/etc/systemd/system/suspend@.service|2=<nowiki>
 +
[Unit]
 +
Description=User suspend actions
 +
Before=sleep.target
  
wm_writeback() {
+
[Service]
    if [ -w /proc/sys/vm/dirty_writeback_centisecs ]; then
+
User=%I
printf "Set VM writeback timeout to %d..." "$1"
+
Type=forking
        echo $1 > /proc/sys/vm/dirty_writeback_centisecs && echo Done. || echo Failed.
+
Environment=DISPLAY=:0
    fi
+
ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ; /usr/bin/mysql -e 'slave stop'
}
+
ExecStart=/usr/bin/sflock
  
case $1 in
+
[Install]
    true)
+
WantedBy=sleep.target</nowiki>}}
wm_writeback '1500'
+
;;
+
    false)
+
wm_writeback '500'
+
;;
+
esac
+
  
exit 0</nowiki>}}
+
{{hc|/etc/systemd/system/resume@.service|2=<nowiki>
 +
[Unit]
 +
Description=User resume actions
 +
After=suspend.target
  
==== Disable NMI Watchdog ====
+
[Service]
{{Hc|head=/etc/pm/power.d/nmi-watchdog|output=
+
User=%I
<nowiki>#!/bin/sh
+
Type=simple
 +
ExecStartPre=/usr/local/bin/ssh-connect.sh
 +
ExecStart=/usr/bin/mysql -e 'slave start'
  
# NMI Watchdog timer power savings
+
[Install]
 +
WantedBy=suspend.target</nowiki>}}
  
nmi_watchdog() {
+
For root/system actions (activate with {{ic|systemctl enable root-suspend}}):
    if [ -w /proc/sys/kernel/nmi_watchdog ]; then
+
        echo $1 > /proc/sys/kernel/nmi_watchdog && echo Done. || echo Failed.
+
    fi
+
}
+
  
case $1 in
+
{{hc|/etc/systemd/system/root-resume.service|2=<nowiki>
    true)
+
[Unit]
echo "Disable NMI Watchdog..."
+
Description=Local system resume actions
nmi_watchdog 0
+
After=suspend.target
;;
+
    false)
+
echo "Enable NMI Watchdog..."
+
nmi_watchdog 1
+
;;
+
esac
+
  
exit 0</nowiki>}}
+
[Service]
 +
Type=simple
 +
ExecStart=/usr/bin/systemctl restart mnt-media.automount
 +
 
 +
[Install]
 +
WantedBy=suspend.target</nowiki>}}
 +
 
 +
{{hc|/etc/systemd/system/root-suspend.service|2=<nowiki>
 +
[Unit]
 +
Description=Local system suspend actions
 +
Before=sleep.target
 +
 
 +
[Service]
 +
Type=simple
 +
ExecStart=-/usr/bin/pkill sshfs
 +
 
 +
[Install]
 +
WantedBy=sleep.target</nowiki>}}
 +
 
 +
A couple of handy hints about these service files (more in {{ic|man systemd.service}}):
 +
* If {{ic|1=<nowiki>Type=OneShot</nowiki>}} then you can use multiple {{ic|1=<nowiki>ExecStart=</nowiki>}} lines. Otherwise only one {{ic|ExecStart}} line is allowed. You can add more commands with either {{ic|ExecStartPre}} or by separating commands with a semicolon (see the first example above; note the spaces before and after the semicolon, as they are ''required'').
 +
* A command prefixed with {{ic|-}} will cause a non-zero exit status to be ignored and treated as a successful command.
 +
* The best place to find errors when troubleshooting these service files is of course with [[Systemd#Journal|journalctl]].
 +
 
 +
==== Combined Suspend/resume service file ====
 +
 
 +
With the combined suspend/resume service file, a single hook does all the work for different phases (sleep/resume) and for different targets (suspend/hibernate/hybrid-sleep).
 +
 
 +
Example and explanation:
 +
 
 +
{{hc|/etc/systemd/system/wicd-sleep.service|2=<nowiki>
 +
[Unit]
 +
Description=Wicd sleep hook
 +
Before=sleep.target
 +
StopWhenUnneeded=yes
 +
 
 +
[Service]
 +
Type=oneshot
 +
RemainAfterExit=yes
 +
ExecStart=-/usr/share/wicd/daemon/suspend.py
 +
ExecStop=-/usr/share/wicd/daemon/autoconnect.py
 +
 
 +
[Install]
 +
WantedBy=sleep.target</nowiki>}}
 +
 
 +
* {{ic|1=<nowiki>RemainAfterExit=yes</nowiki>}}: After started, the service is considered active until it is explicitly stopped.
 +
* {{ic|1=<nowiki>StopWhenUnneeded=yes</nowiki>}}: When active, the service will be stopped if no other active service requires it. In this specific example, it will be stopped after ''sleep.target'' is stopped.
 +
* Because ''sleep.target'' is pulled in by ''suspend.target'', ''hibernate.target'' and ''hybrid-sleep.target'' and ''sleep.target'' itself is a ''StopWhenUnneeded'' service, the hook is guaranteed to start/stop properly for different tasks.
 +
 
 +
==== Hooks in /usr/lib/systemd/system-sleep ====
 +
 
 +
''systemd'' runs all executables in {{ic|/usr/lib/systemd/system-sleep/}}, passing two arguments to each of them:
 +
 
 +
* Argument 1: either {{ic|pre}} or {{ic|post}}, depending on whether the machine is going to sleep or waking up
 +
* Argument 2: {{ic|suspend}}, {{ic|hibernate}} or {{ic|hybrid-sleep}}, depending on which is being invoked
 +
 
 +
In contrast to [[pm-utils]], ''systemd'' will run these scripts concurrently and not one after another.
 +
 
 +
The output of any custom script will be logged by ''systemd-suspend.service'', ''systemd-hibernate.service'' or ''systemd-hybrid-sleep.service''. You can see its output in ''systemd''<nowiki>'</nowiki>s [[systemd#Journal|journal]]:
 +
# journalctl -b -u systemd-suspend
 +
 
 +
{{Note|You can also use ''sleep.target'', ''suspend.target'', ''hibernate.target'' or ''hybrid-sleep.target'' to hook units into the sleep state logic instead of using custom scripts.}}
 +
 
 +
An example of a custom sleep script:
 +
 
 +
{{hc|/usr/lib/systemd/system-sleep/example.sh|
 +
#!/bin/sh
 +
case $1/$2 in
 +
  pre/*)
 +
    echo "Going to $2..."
 +
    ;;
 +
  post/*)
 +
    echo "Waking up from $2..."
 +
    ;;
 +
esac}}
 +
 
 +
Do not forget to make your script executable:
 +
# chmod a+x /usr/lib/systemd/system-sleep/example.sh
 +
 
 +
See {{ic|man 7 systemd.special}} and {{ic|man 8 systemd-sleep}} for more details.
 +
 
 +
== Troubleshooting ==
 +
 
 +
=== Enable RC6 Power Save Options ===
 +
 
 +
{{Merge||find some better place for this section}}
 +
{{Expansion|describe the states better; it may be platform dependent}}
 +
 
 +
  i915_enable_rc6=#Nr
 +
Where ''#Nr'':
 +
* '''1''': enable rc6
 +
* '''3''': enable rc6 and deep rc6
 +
* '''5''': enable rc6 and deepest rc6
 +
* '''7''': enable rc6, deep and deepest rc6
  
 
== See Also ==
 
== See Also ==
[[CPU Frequency Scaling]]
+
* [[Laptop#Power management]] describes power management specific for laptops - especially battery monitoring.
 +
* [[General Recommendations#Power management]]

Revision as of 15:21, 29 September 2013

Summary help replacing me
Describes power management in Arch Linux.
Related
Power saving
Display Power Management Signaling
Suspend and Hibernate

The purpose of this page is to provide general overview of power management in Arch Linux. As Arch Linux uses systemd as system manager, this article focuses on it.

There are multiple places where one can change power management settings:

There are also many power management tools:

Note: Power settings you set in one place/tool could be overwritten in another place/tool.

Power management with systemd

ACPI events

systemd handles some power-related ACPI events. They can be configured via the following options from /etc/systemd/logind.conf:

  • HandlePowerKey: specifies which action is invoked when the power key is pressed.
  • HandleSuspendKey: specifies which action is invoked when the suspend key is pressed.
  • HandleHibernateKey: specifies which action is invoked when the hibernate key is pressed.
  • HandleLidSwitch: specifies which action is invoked when the lid is closed.

The specified action can be one of ignore, poweroff, reboot, halt, suspend, hibernate, hybrid-sleep, lock or kexec.

If these options are not configured, systemd will use its defaults: HandlePowerKey=poweroff, HandleSuspendKey=suspend, HandleHibernateKey=hibernate, and HandleLidSwitch=suspend.

On systems which run no graphical setup or only a simple window manager like i3 or awesome, this may replace the acpid daemon which is usually used to react to these ACPI events.

Note:
  • Run systemctl restart systemd-logind for your changes to take effect.
  • systemd cannot handle AC and Battery ACPI events, so if you use Laptop Mode Tools or other similar tools acpid is still required.

In the current version of systemd, the Handle* options will apply throughout the system unless they are "inhibited" (temporarily turned off) by a program, such as a power manager inside a desktop environment. If these inhibits are not taken, you can end up with a situation where systemd suspends your system, then when it wakes up the other power manager suspends it again.

Warning: Currently, the power managers in the newest versions of KDE and GNOME are the only ones that issue the necessary "inhibited" commands. Until the others do, you will need to set the Handle options to ignore if you want your ACPI events to be handled by Xfce, acpid or other programs.

Suspend and hibernate

systemd provides commands for suspend to RAM, hibernate and a hybrid suspend using the kernel's native suspend/resume functionality. There are also mechanisms to add hooks to customize pre- and post-suspend actions.

Note: systemd can also use other suspend backends (such as Uswsusp or TuxOnIce), in addition to the default kernel backend, in order to put the computer to sleep or hibernate. See Uswsusp#With systemd for an example.

systemctl suspend should work out of the box, for systemctl hibernate to work on your system you need to follow the instructions at Suspend and Hibernate#Hibernation.

Sleep hooks

systemd does not use pm-utils to put the machine to sleep when using systemctl suspend, systemctl hibernate or systemctl hybrid-sleep; pm-utils hooks, including any custom hooks, will not be run. However, systemd provides two similar mechanisms to run custom scripts on these events.

Suspend/resume service files

Service files can be hooked into suspend.target, hibernate.target and sleep.target to execute actions before or after suspend/hibernate. Separate files should be created for user actions and root/system actions. To activate the user service files run systemctl enable suspend@user && systemctl enable resume@user. Examples:

/etc/systemd/system/suspend@.service
[Unit]
Description=User suspend actions
Before=sleep.target

[Service]
User=%I
Type=forking
Environment=DISPLAY=:0
ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ; /usr/bin/mysql -e 'slave stop'
ExecStart=/usr/bin/sflock

[Install]
WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit]
Description=User resume actions
After=suspend.target

[Service]
User=%I
Type=simple
ExecStartPre=/usr/local/bin/ssh-connect.sh
ExecStart=/usr/bin/mysql -e 'slave start'

[Install]
WantedBy=suspend.target

For root/system actions (activate with systemctl enable root-suspend):

/etc/systemd/system/root-resume.service
[Unit]
Description=Local system resume actions
After=suspend.target

[Service]
Type=simple
ExecStart=/usr/bin/systemctl restart mnt-media.automount

[Install]
WantedBy=suspend.target
/etc/systemd/system/root-suspend.service
[Unit]
Description=Local system suspend actions
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/pkill sshfs

[Install]
WantedBy=sleep.target

A couple of handy hints about these service files (more in man systemd.service):

  • If Type=OneShot then you can use multiple ExecStart= lines. Otherwise only one ExecStart line is allowed. You can add more commands with either ExecStartPre or by separating commands with a semicolon (see the first example above; note the spaces before and after the semicolon, as they are required).
  • A command prefixed with - will cause a non-zero exit status to be ignored and treated as a successful command.
  • The best place to find errors when troubleshooting these service files is of course with journalctl.

Combined Suspend/resume service file

With the combined suspend/resume service file, a single hook does all the work for different phases (sleep/resume) and for different targets (suspend/hibernate/hybrid-sleep).

Example and explanation:

/etc/systemd/system/wicd-sleep.service
[Unit]
Description=Wicd sleep hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/usr/share/wicd/daemon/suspend.py
ExecStop=-/usr/share/wicd/daemon/autoconnect.py

[Install]
WantedBy=sleep.target
  • RemainAfterExit=yes: After started, the service is considered active until it is explicitly stopped.
  • StopWhenUnneeded=yes: When active, the service will be stopped if no other active service requires it. In this specific example, it will be stopped after sleep.target is stopped.
  • Because sleep.target is pulled in by suspend.target, hibernate.target and hybrid-sleep.target and sleep.target itself is a StopWhenUnneeded service, the hook is guaranteed to start/stop properly for different tasks.

Hooks in /usr/lib/systemd/system-sleep

systemd runs all executables in /usr/lib/systemd/system-sleep/, passing two arguments to each of them:

  • Argument 1: either pre or post, depending on whether the machine is going to sleep or waking up
  • Argument 2: suspend, hibernate or hybrid-sleep, depending on which is being invoked

In contrast to pm-utils, systemd will run these scripts concurrently and not one after another.

The output of any custom script will be logged by systemd-suspend.service, systemd-hibernate.service or systemd-hybrid-sleep.service. You can see its output in systemd's journal:

# journalctl -b -u systemd-suspend
Note: You can also use sleep.target, suspend.target, hibernate.target or hybrid-sleep.target to hook units into the sleep state logic instead of using custom scripts.

An example of a custom sleep script:

/usr/lib/systemd/system-sleep/example.sh
#!/bin/sh
case $1/$2 in
  pre/*)
    echo "Going to $2..."
    ;;
  post/*)
    echo "Waking up from $2..."
    ;;
esac

Do not forget to make your script executable:

# chmod a+x /usr/lib/systemd/system-sleep/example.sh

See man 7 systemd.special and man 8 systemd-sleep for more details.

Troubleshooting

Enable RC6 Power Save Options

Merge-arrows-2.pngThis article or section is a candidate for merging with [[]].Merge-arrows-2.png

Notes: find some better place for this section (Discuss in Talk:Power management#)

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: describe the states better; it may be platform dependent (Discuss in Talk:Power management#)
 i915_enable_rc6=#Nr

Where #Nr:

  • 1: enable rc6
  • 3: enable rc6 and deep rc6
  • 5: enable rc6 and deepest rc6
  • 7: enable rc6, deep and deepest rc6

See Also