電源管理/復帰トリガー

提供: ArchWiki
2022年7月23日 (土) 09:04時点におけるNy-a (トーク | 投稿記録)による版 (Template:TranslationStatus を追加)
ナビゲーションに移動 検索に移動

関連記事

復帰トリガー(ウェイクアップトリガー)とは、ハードウェアの任意の省電力状態からシステムを復帰させることのできるイベント要因です。自明な例としては、電源ボタンやスリープボタン、Wake-on-LAN 機能、ノートパソコンのリッドスイッチがあります。復帰トリガーは、以下に挙げる様々なカーネルインターフェイスにより制御できます。すべての可能なトリガーをカバーする統一されたインターフェイスは存在しません。

復帰トリガーインターフェイス

/proc/acpi/wakeup

/proc/acpi/wakeup ファイルを読み出すと、ACPI に登録されているウェイクアップ要因のリストが得られます。利用可能であれば、対応する sysfs も得られます。Device 列のエントリをそのファイルに書き込めば、状態を切り替えることができます。例えば、ラップトップを開いたときの復帰を無効化するには:

# echo "LID" > /proc/acpi/wakeup

/sys/module/acpi/parameters/ec_no_wakeup

このファイルは ACPI カーネルモジュールオプション ec_no_wakeup の値を表しています。このオプションは、システムが suspend-to-idle (s2idle)電源状態にあるときに組み込みコントローラからの復帰トリガーを渡すかどうかを制御します[1]。最近のノートパソコンでは、一部のケースで組み込みコントローラの復帰によりバッテリーの過剰な消耗を引き起こすことがあります。

/sys/devices/

復帰をサポートする sysfs デバイスには、デバイスの power サブディレクトリ内の wakeup ファイルがそれぞれ含まれています。このファイルには、復帰トリガーの状態が含まれ、書き込むこともできます。バスコントローラとエンドポイントデバイスは、システムを復帰させることができる可能性があります。例えば、USB コントローラ(バス)からの復帰を無効化するには:

# echo "disabled" > /sys/bus/usb/devices/usb1/power/wakeup

コントローラの設定に関わらず、トリガーが有効化されていれば、エンドポイントデバイスはデバイスを復帰させることができるはずです。しかし、これはハードウェア依存である可能性があります。

sysfsPowerTOP インターフェイスをプログラムしてください。ただし、/sys/class/net//sys/bus/usb/devices/ (/sys/devices/ へのシンボリックリンクを含みます)を読み出しても、ネットワーキングデバイスと USB デバイスの復帰トリガーしか得られません。

/sys/class/wakeup/*

/sys/class/wakeup ディレクトリにほぼすべての復帰トリガーがあります。このディレクトリは、関連するすべてのデバイスへのシンボリックリンクを含みます。サブディレクトリを見れば、可能な復帰トリガーを探すのに便利です。一部のトリガーは仮想デバイスに対応している可能性があります。一方、ハードウェア関連の復帰トリガーは、以下のファイルのうち少なくとも1つが含まれています:

/sys/class/wakeup/*/device/physical_node/power/wakeup
/sys/class/wakeup/*/device/power/wakeup

/sys/class/wakeup 内の復帰トリガーのいくつかは、以下のファイルが存在する、暗号化された /proc/acpi/wakeup 名へのリンクを提供します:

/sys/class/wakeup/*/device/path

永続的な設定

The one-time methods should suffice for setting the /proc/acpi/wakeup states and acpi.ec_no_wakeups kernel parameter while the event-driven approach with udev is the reliable way to configure the sysfs devices.

One-time with systemd

The ec_no_wakeups ACPI kernel module option can be set at boot as described in the article. The standard solution to set the sysfs values at boot are systemd services such as in this troubleshooting case. Another systemd-based manager for /proc/acpi/wakeup is wakeup-triggersAUR.

Some systems can override some of the ACPI wakeup triggers upon power state transition(s) in what is more of a bug rather than a feature. If the hardware is overriding triggers at predictable times that can still be solved with appropriately crafted systemd units. The sleep.target is a generic target covering all different suspended states that might be helpful in this case, but there is no generic wakeup.target [2].

This method only works reliably with sysfs devices that are connected all the time.

Event-driven with udev

Setting the wakeup trigger status with udev rules is an event-driven method that works reliably any time the devices with wakeup triggers are connected. The key is to detect an addition of a new device (ACTION=="add") in a rule and set the wakeup trigger status with ATTR{power/wakeup}="disabled". If the hardware is resetting this setting, udev can try to circumvent it by reapplying rules upon every device change (ACTION=="add|change"). A device tree with possible parameters for matching a particular device found in sysfs can be obtained with udevadm info -q all -a /sys/devices/....

A representative common example here would be a Logitech Unifying USB receiver. Its wakeup trigger should be enabled by default and if that is not desired, a solution could be an udev rule, as follows:

/etc/udev/rules.d/logitech-unifying.rules
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", ATTR{power/wakeup}="disabled"

The reverse case to enable the necessary trigger(s) is described in the udev article.

udev triggers so early in the device enumeration that disabling wakeup trigger with the method above causes (some?) disabled triggers to not be listed in /sys/class/wakeup. That might be dependent on whether the device was already present at boot and needs further clarification.

トラブルシューティング

デバイスやバスのツリーを一覧表示する

これらの補助コマンドは、特定のシステムにあるすべての復帰トリガーを把握したい時や、udev ルールを記述したり、一般的な復帰ソースのトラブルシューティングをしたりする時に便利です:

# lshw -businfo -numeric
# lspci -DPPnn
# lsusb -tvv

サスペンドからすぐに復帰する

LynxPoint や LynxPoint-LP チップセットが搭載された Intel Haswell の場合、サスペンドからすぐに復帰してしまうと報告されています。BIOS の ACPI 実装に問題があり起動時に xhci_hcd モジュールによって ACPI イベントが解釈されてしまうのが原因です。解決策としてカーネルによってケースバイケースで問題のあるシステムがブラックリスト (XHCI_SPURIOUS_WAKEUP) に追加されています [3]

サスペンド中に USB デバイスを接続したときなどに ACPI の復帰トリガーが有効になって復帰してしまいます。ブラックリストに追加されるまで一時的な応急処置としては復帰トリガーを無効化する方法があります。以下の設定で USB による復帰を無効化することができます [4]

現在の設定を確認:

$ cat /proc/acpi/wakeup
Device  S-state   Status   Sysfs node
...
EHC1      S3    *enabled  pci:0000:00:1d.0
EHC2      S3    *enabled  pci:0000:00:1a.0
XHC       S3    *enabled  pci:0000:00:14.0
...

問題のデバイスは EHC1, EHC1, XHC (USB 3.0) です。状態を変更するには root でデバイス名をファイルに echo してください:

# echo EHC1 > /proc/acpi/wakeup
# echo EHC2 > /proc/acpi/wakeup
# echo XHC > /proc/acpi/wakeup

上記のコマンドでサスペンドが再度機能するようになります。ただし、設定は一時的なものなので再起動するたびに設定し直す必要があります。自動化したい場合は systemd#ユニットファイルを見てください。詳しくは BBS スレッド を参照。

nouveau ドライバ

nouveau ドライバを使用している場合、サスペンドから即座に復帰してしまう原因はドライバのバグかもしれません(時々 GPU のサスペンドを妨げてしまいます)。回避策は、スリープする直前に nouveau カーネルモジュールをアンロードして、復帰した時に再びロードすることです。これを行うには、以下のスクリプトを作成してください:

/usr/lib/systemd/system-sleep/10-nouveau.sh
#!/bin/bash

case $1/$2 in
  pre/*)
    # echo "Going to $2..."
    /usr/bin/echo "0" > /sys/class/vtconsole/vtcon1/bind
    /usr/bin/rmmod nouveau
    ;;
  post/*)
    # echo "Waking up from $2..."
    /usr/bin/modprobe nouveau
    /usr/bin/echo "1" > /sys/class/vtconsole/vtcon1/bind
    ;;
esac

1つ目の echo 行は、フレームバッファコンソールドライバ(fbcon)から nouveaufb をアンバインドします。通常、この例にあるように vtcon1 ですが、他の vtcon* である場合もあります。どれがフレームバッファデバイスであるかは /sys/class/vtconsole/vtcon*/name を確認してください[5]

翻訳ステータス: このページは en:Wakeup triggers の翻訳バージョンです。最後の翻訳日は 2022-07-22 です。もし英語版に 変更 があれば、翻訳の同期を手伝うことができます。