Pages

Tuesday, July 16, 2013

Suspend to disk/ram with Linux

This article describes the following topics:

Suspend to disk
Suspend to ram
Stand-By
Configure buttons for ACPI events
Issues with KDE
Issues with VT6102 (Via Rhine NIC)

All of the following was configured with the current Slackware release (14.0) on my personal notebook (running KDE) and my HTPC (running XBMC).

Suspend to disk

Before you suspend your computer to disk make sure that your computer support this mode. You can do this easily by looking at the file /sys/power/state:

# cat /sys/power/state
mem disk


Every mode listed above is supported by your system in general. When your system supports suspend to disk then you need to modify your boot loader first. The trick is that Linux will write down the memory content to your swap partition when executing suspend to disk. On the next boot the Linux Kernel will then look at your swap area to check for available 'suspend-to-disk' images and load them. First check where your Swap partition resides:

# grep swap /etc/fstab
/dev/sda2        swap             swap        defaults         0   0


Then edit /etc/lilo.conf and add resume=/dev/sda2 to the append line like this (where /dev/sda2 should be replaced with your Swap partition):

# vi /etc/lilo.conf
...
append=" vt.default_utf8=0 resume=/dev/sda2 raid=noautodetect"
...


And reinstall lilo:

# lilo
Added Linux  *
...


Now close all critical application, save all unsaved data etc. and suspend your computer to disk:

# echo disk > /sys/power/state

It will take some seconds to write down the memory content to your swap partition and then your computer will turn off. On my notebook and my HTPC the power LED is off and the computer itself seems to be completely off. When I turn my computer (either my notebook or my HTPC) back on then the bios screen appears as usual followed by Lilo. After some time the default Linux Kernel will be loaded. When the Linux Kernel was loaded some different message will appear like this:

...loading and decompressing image data...

That indicates that the Linux Kernel loads the prior saved memory image back to ram and execute it. After that your identical session should be restored. Even my HTPC with XBMC continues playing movies that were stopped during suspend to disk which is very cool.
Note that this mode does not consumes battery power. In case of a power loss the system will resume from hard disk normally as nothing has happened.

Suspend to ram

Suspend to ram should work out of box without any configurations. Just check if your computer supports suspend to ram by looking at /sys/power/state:

# cat /sys/power/state
mem disk


If the above output lists mem then suspend to ram is supported in general. Just save your unsaved data and suspend your computer to ram:

# echo mem > /sys/power/state

Your computer should suspend to ram very quickly and then turn off. Then the power LED will blink slowly. Pressing the power button will turn back on your computer very quickly again. The bios screeen will be skipped also loading the Linux Kernel etc.
Note that this mode consumes battery power. In case of a power loss your system can not resume. It will start by booting from hard disk as usual.

Stand-By

When your hardware supports stand-by then no more changes to the system are necessary.  First check if your system supports stand-by by looking at /sys/power/state:

# cat /sys/power/state
standby mem disk

To enter stand-by mode run the following command:

# echo standby > /sys/power/state

In stand-by mode the CPU will be halted, everything else keeps running (hard disk(s), fan(s) etc).
Note that this mode consumes battery power. In case of a power loss your system can not resume. It will start by booting from hard disk as usual.

Configure buttons for ACPI events

You can configure various buttons for ACPI events. Eg. I like to suspend to ram my notebook when I close the lid. Also shutting down my notebook (or HTPC) when pressing the power button spend to much time (imho). So I configured my notebook in two ways:

1. Suspend to ram when closing the lid
2. Suspend to disk when pressing the power button

In Slackware there is an extremely easy way to achive this goal (and more or less preconfigured). Under /etc/acpi/ exists a script called acpi_handler.sh which could handle everything you need. By default it will only shutdown your computer when you press the power button and log all other unconfigured ACPI events to /var/log/messages. Just edit the script like the following:

# cp /etc/acpi/acpi_handler.sh /etc/acpi/acpi_handler.sh.orig
# vi /etc/acpi/acpi_handler.sh
...
  button)
    case "$2" in
      #power) /sbin/init 0
      power) /bin/echo disk > /sys/power/state
         ;;
      lid) /bin/echo mem > /sys/power/state
         ;;
...


With the above changes your computer will suspend to disk when pressing the power button and suspend to ram when closing the lid of your notebook. The changes in this script will take effect immediatly and there is no need to restart any daemons etc.
I have written two scripts for suspending to ram/disk that will take a little care of a few things I've figured out. One thing is that I use NFS a lot. After resuming the NFS mount point may not be accessable any more. Another thing is that I like to use KDE. When pressing the power button or closing the lid of my notebook then KDE shows the password dialog after resuming. During this time the entire screen is visible one second. To avoid that I have added a sleep command to the scripts. Enough said, here are my scripts:

# vi /etc/acpi/suspend_to_ram.sh
#!/bin/sh
/sbin/umount -a -t nfs
/usr/bin/sleep 2
/bin/echo mem > /sys/power/state
 

# vi /etc/acpi/suspend_to_disk.sh
#!/bin/sh
/sbin/umount -a -t nfs
/usr/bin/sleep 2
/bin/echo disk > /sys/power/state


Both scripts are more or less the same. First they unmount any mounted NFS shares. Then the script will sleep for two seconds giving a desktop environment like KDE enough time to lock the screen. Finally they suspend to ram/disk. Both scripts have to be added to the /etc/acpi/acpi_handler.sh script instead of suspend to ram/disk commands.

Issues with KDE

I use KDE as my WM on my notebook. Also I have configured my power button to suspend to disk when pressed. When I suspended my notebook to disk while KDE is running and turn it back on then the KDE's logout screen appears:


This is not a real KDE issue, I just configured the power button twice: one was already configured in KDE and one more time in /etc/acpi/acpi_handler.sh (see above). Since /etc/acpi/acpi_handler.sh is WM independent I only want to use this configuration and not the KDE configuration. To disable the power button in KDE open the 'System Setting' in KDE first. Then follow 'Hardware' and then 'Power Management'. Finally click on 'Energy Saving Settings' and the follwoing screen should appear:


There are two methods to disable the power button in KDE:

1: Uncheck 'Button events handling'
2: Choose 'Do nothing' in the drop down menu for the option 'When power button pressed'

If you want to display the KDE password dialog after resuming then select 'Lock screen' instead of 'Do nothing'.

Issues with VT6102 (Via Rhine NIC)

In my old workstation I've a Via Rhine NIC which causes problems with the suspend to disk mode. This is the NIC which is build in:

# lspci
...
00:12.0 Ethernet controller: VIA Technologies, Inc. VT6102 [Rhine-II] (rev 74)
...


Everytime I tried to suspend to disk my workstation it came up with the following message:

# echo disk > /sys/power/state
-bash: echo: write error: No such device


It did some research but I couldn't find the cause for this behaviour. Looking at logs didn't really showed a clue where to look. At this point I gave up and I thought the Bios might be buggy or else. Later I played a little with wake on lan with the workstation and for any reason I looked at the parameters for the via_rhine module:

# modinfo via_rhine
...
parm: debug:VIA Rhine debug message flags (int)
parm: rx_copybreak:VIA Rhine copy breakpoint for copy-only-tiny-frames (int)
parm: avoid_D3:Avoid power state D3 (work-around for broken BIOSes) (bool)


The last parameter looked like something that has to do with ACPI etc. So I gave it a try. First I created the modprobe configuration file for the via_rhine module to load the module with the avoid_D3 parameter:

# vi /etc/modprobe.d/via_rhine.conf
options via_rhine avoid_D3=1


Then I rebooted the workstation:

# shutdown -r now
...


After the reboot finished I took a look at dmesg:

# dmesg | grep via_rhine
[    5.754684] via_rhine: v1.10-LK1.5.1 2010-10-09 Written by Donald Becker
[    5.754696] via_rhine: avoid_D3 set
[    5.792407] via-rhine 0000:00:12.0 eth0: VIA Rhine II at 0xdfffe600, 00:0c:6e:2a:d4:6b, IRQ 23
[    5.793190] via-rhine 0000:00:12.0 eth0: MII PHY found at address 1, status 0x786d advertising 05e1 Link cde1


Clearly the avoid_D3 parameter was set. And more surprising I could suspend my workstation to disk successfully.

Updated 10/06/2015: added the passage 'Issues with VT6102 (Via Rhine NIC)'