Chapter 11. Power management

Table of Contents

11.1. Basic power management commands
11.1.1. Powering off or rebooting the system
11.1.2. Using ACPI sleep states (suspend and resume)
11.1.3. Suspending and resuming individual devices
11.1.4. Adjusting CPU frequency at runtime
11.1.5. Using IEEE 802.11 (Wi-Fi) power saving mode
11.2. Sensors and monitoring
11.3. An introduction to powerd
11.3.1. Example: using powerd to suspend on lid close
11.3.2. Example: reducing CPU frequency when unplugged

For power management, NetBSD supports sensor monitoring (including battery state, CPU temperature, and so on), CPU frequency adjustment, low-power mode for devices, hardware poweroff, and sleep (suspend-to-RAM) on some hardware.

Power management on NetBSD primarily takes the form of acpi(4) (Advanced Configuration and Power Interface) support, although sensors are also supported on many other types of non-ACPI hardware.

11.1. Basic power management commands

11.1.1. Powering off or rebooting the system

A NetBSD system with ACPI support can be physically powered off by running the poweroff(8) and reboot(8) commands, however, it is usually best to use shutdown(8) so the system shuts down with appropriate warning and has time to properly stop any running applications and services.

Shut the system down immediately:

# shutdown -p now

Reboot with a 10 minute warning to any users:

# shutdown -r +10

11.1.2. Using ACPI sleep states (suspend and resume)

An ACPI system is always in one of any "sleep states":

S0

fully running

S1

power on suspend (CPU and hard disks are off)

S2

similar to S3, usually not implemented

S3

suspend-to-RAM ("sleep", most of the system is inactive to save power, but can quickly be brought back up)

S4

suspend-to-disk ("hibernate", not currently supported on NetBSD)

S5

powered off

The sleep state can be modified with sysctl(8), e.g. to suspend-to-RAM:

# sysctl -w hw.acpi.sleep.state=3

The way the system wakes up is dependent on the hardware, and may include pressing the power button or lifting the lid. If supported, the system can resume from a suspended state much quicker than a full reboot.

If you've tested this and verified it works as expected, you may wish to trigger it automatically through a powerd(8) event, such as closing the lid of a laptop.

11.1.3. Suspending and resuming individual devices

If your machine does not support full ACPI suspend and resume, it may still be possible to suspend and resume individual devices to save power while they are inactive. This can be accomplished with drvctl(8).

For example, /var/run/dmesg.boot reports our hardware has a SD card reader, rtsx0.

rtsx0 at pci1 dev 0 function 0: Realtek Semiconductor RTS5227 PCI-E Card Reader (rev. 0x01)
rtsx0: interrupting at msi4 vec 0
sdmmc0 at rtsx0

We can suspend it:

# drvctl -S rtsx0

And we can also resume it:

# drvctl -R rtsx0

If a specific device is failing to suspend or resume, this can also be used for debugging.

11.1.4. Adjusting CPU frequency at runtime

Many modern machines allow the CPU frequency to be dynamically adjusted. A higher frequency provides better performance, but increased battery usage and generates more heat. On NetBSD, CPU frequency can be adjusted at runtime with sysctl(8).

For example, this machine is currently running at 1400 MHz, but also supports a 600 MHz low-power mode:

$ sysctl -a | grep freq
machdep.cpu.frequency.target = 1400
machdep.cpu.frequency.current = 1400
machdep.cpu.frequency.min = 600
machdep.cpu.frequency.max = 1400
machdep.cpu.frequency.available = 600 1400

We can enter the low power mode by setting the target frequency:

# sysctl -w machdep.cpu.frequency.target=600

Many modern hardware supports an "automatic adjustment" frequency, usually this will be a reported frequency that ends in 1. On systems without this functionality, sysutils/estd can be installed from pkgsrc to perform automatic adjustment depending on load in software, although it will be less efficient than hardware scaling.

11.1.5. Using IEEE 802.11 (Wi-Fi) power saving mode

Some IEEE 802.11 (Wi-Fi) networking devices support a low power mode, which can be enabled with ifconfig(8):

# ifconfig iwm0 powersave

You may notice an increase in reported latency from ping(8) and a decrease in performance. However, it may improve your device's battery life, as the radios in such devices can consume a lot of energy. It can be disabled again with ifconfig:

# ifconfig iwm0 -powersave

11.2. Sensors and monitoring

The primary command-line frontend to NetBSD's sensor monitoring framework is envstat(8). Here is a typical example of envstat output:

$ envstat
                      Current  CritMax  WarnMax  WarnMin  CritMin  Unit
[acpiacad0]
         connected:     FALSE
[acpibat0]
           present:      TRUE
    design voltage:    11.100                                         V
           voltage:    12.270                                         V
        design cap:    23.200                                        Wh
     last full cap:    16.940                                        Wh
            charge:    16.770                      5.000%   1.181%   Wh (99.00%)
       charge rate:       N/A
    discharge rate:       N/A
          charging:     FALSE
      charge state:    NORMAL
[acpitz0]
       temperature:    48.000  128.000
    

acpiacad0 is the machine's AC adapter. It is not currently connected.

acpibat0 is the machine's battery, currently 99% full. At 5%, a warning will be printed to the console and an event sent to powerd(8). At 1%, the system will shut down to prevent data loss from loss of power.

A CPU temperature sensor is also detected, acpitz0. It indicates that the CPU's current temperature is 48 degrees Celsius, and the critical temperature is 128 degrees Celsius. If the critical temperature is reached, the system will shut down to prevent damage to hardware. powerd(8) can be notified of changes in temperature.

11.3. An introduction to powerd

powerd(8) is a daemon that allows the system to respond to power management events, such as the AC adapter being unplugged, battery state changing, a laptop's lid being closed, or a "sleep" button being pressed.

As with other services, powerd can be enabled by editing /etc/rc.conf:

      powerd=YES
    

And started with service(8):

# service powerd start

powerd works by executing a named sh(1) script from the directory /etc/powerd/scripts whenever a power event occurs. We can use commands we learned in previous sections of this chapter to our advantage in the scripts.

11.3.1. Example: using powerd to suspend on lid close

Example 11.1. /etc/powerd/scripts/lid_switch

#!/bin/sh -
#
#	$NetBSD: chap-power.html,v 1.17 2021/12/14 17:15:55 snj Exp $
#
# Generic script for lid switch events.
#
# Arguments passed by powerd(8):
#
#	device event

case "${2}" in
pressed)
	# Lock the X11 display to prevent tampering
	DISPLAY=:0 /usr/pkg/bin/xlock -mode blank &
	# Wait for 1 second
	sleep 1
	# Suspend
	/sbin/sysctl -w hw.acpi.sleep.state=3
	exit 0
	;;

released)
	exit 0
	;;

*)
	logger -p warning "${0}: unsupported event ${2} on device ${1}" >&1
	exit 1
esac

11.3.2. Example: reducing CPU frequency when unplugged

Example 11.2. /etc/powerd/scripts/acadapter

#!/bin/sh -
#
#	$NetBSD: chap-power.html,v 1.17 2021/12/14 17:15:55 snj Exp $
#
# Generic script for acadapter events.
#
# Arguments passed by powerd(8):
#
#	device event

case "${2}" in
pressed)
	logger -p info "${0}: Full performance mode" >&1

	# Disable power saving mode on all network interfaces.
	for intf in $(/sbin/ifconfig -l); do
		/sbin/ifconfig $intf -powersave >/dev/null 2>&1
	done

	# Increase CPU frequency
	/sbin/sysctl -w machdep.cpu.frequency.target=2300

	exit 0
	;;

released)
	logger -p info "${0}: Power saving mode" >&1

	# Enable power saving mode on all network interfaces.
	for intf in $(/sbin/ifconfig -l); do
		/sbin/ifconfig $intf powersave >/dev/null 2>&1
	done

	# Reduce CPU frequency
	/sbin/sysctl -w machdep.cpu.frequency.target=1400

	exit 0
	;;

*)
	logger -p warning "${0}: unsupported event ${2} on device ${1}" >&1
	exit 1
	;;
esac