電源管理
関連記事
電源管理とは、アクティブでない時に電源を切ったりシステムのコンポーネントを低電力状態に切り替えたりする機能です。
Arch Linux では、電源管理は主に2つの部分からなります:
- Linux カーネルの設定。ハードウェアと対話します。
- ユーザスペースのツールの設定。カーネルと対話し、カーネルのイベントに応答します。ユーザスペースのツールの多くは、"ユーザフレンドリー"な方法でカーネルの設定を変更することもできます。利用可能なツールは #ユーザースペースツール を参照してください。
目次
ユーザースペースツール
以下のツールを使うことで、大量の設定を手動で設定しなくて済みます。どのツールも多かれ少なかれ同じような動作をするので、衝突を避けるためにツールはどれか一つだけを実行してください。電源管理カテゴリを見れば、Arch Linux にどんな電源管理の選択肢が存在するかわかります。
以下は省電力設定をするために作られた人気のあるスクリプトやツールです:
コンソール
- acpid — ACPI の電源管理イベントを届けるデーモン。netlink をサポート。
- Laptop Mode Tools — ノートパソコンの省電力設定をするユーティリティ。多少設定が要りますが省電力設定ユーティリティのデファクトスタンダードとされています。
- libsmbios — Dell SMBIOS テーブルと対話するためのライブラリおよびツール。
- powertop — 消費電力や電源管理の問題を診断して省電力設定を補助するツール。
- systemd — システムおよびサービスマネージャ。
- TLP — Linux 向けの先進的な電源管理。
グラフィカル
- batsignal — libnotify を使用してバッテリレベルの低下を警告する軽量バッテリモニタ。
- cbatticon — 軽量で高速なバッテリアイコンをシステムトレイに表示。
- GNOME Power Statistics — GNOME のシステム電力情報および統計。
- KDE Power Devil — Plasma 用の電源管理モジュール。
- LXQt Power Management — LXQt 用の電源管理モジュール。
- MATE Power Management — MATE 用電源管理ツール。
- MATE Power Statistics — MATE のシステム電力情報と統計。
- poweralertd — UPower 通知を伝播するデーモン。
- powerkit — デスクトップに依存しない電源マネージャー。
- Xfce Power Manager — Xfce 用の電源マネージャ。
- vattery — システムトレイ内のラップトップバッテリのステータスを表示する、 Vala で書かれたバッテリ監視アプリケーション。
電源管理
ACPI イベント
systemd は一部の電源関連の ACPI イベントを処理します。これらのイベントの動作は /etc/systemd/logind.conf
や /etc/systemd/logind.conf.d/*.conf
で設定できます (logind.conf(5) を参照)。専用の電源マネージャを持たないシステムでは、この方法は acpid デーモンの代わりになりえます。ちなみに、acpid は通常、ACPI イベントに対応するために使われるデーモンです。
イベントの動作には、ignore
、poweroff
、reboot
、halt
、suspend
、hibernate
、hybrid-sleep
、suspend-then-hibernate
、lock
、kexec
のいずれかを指定することができます。ハイバーネートとサスペンドの場合は、適切にセットアップしなければなりません。イベントが設定されていない場合、systemd はデフォルトの動作を使用します。
イベントハンドラ | 説明 | デフォルトの動作 |
---|---|---|
HandlePowerKey
|
電源キー/ボタンが押された時にトリガされます。 | poweroff
|
HandleSuspendKey
|
サスペンドキー/ボタンが押された時にトリガされます。 | suspend
|
HandleHibernateKey
|
ハイバネートキー/ボタンが押された時にトリガされます。 | hibernate
|
HandleLidSwitch
|
ラップトップPCなどの蓋が閉じられた時に (以下のケースを除いて) トリガされます。 | suspend
|
HandleLidSwitchDocked
|
システムがドッキングステーションに繋がれている場合や、複数のディスプレイに繋がれている場合に蓋が閉じられるとトリガされます。 | ignore
|
HandleLidSwitchExternalPower
|
システムが外部電源に接続されている状況で蓋が閉じられた時にトリガされます。 | HandleLidSwitch に対して設定されている動作
|
変更を適用するには systemd-logind
に対して HUP
シグナルを発行して下さい:
# systemctl kill -s HUP systemd-logind
電源マネージャ
一部のデスクトップ環境には、systemd の ACPI 設定の一部あるいは全てを inhibit する (一時的にオフにする) 電源マネージャが含まれています。そのような電源マネージャが実行されている場合、電源マネージャだけで ACPI イベントに対する動作を設定することができます。/etc/systemd/logind.conf
や /etc/systemd/logind.conf.d/*.conf
を変更する必要があるのは、電源マネージャによって inhibit されていないイベントに対する挙動を設定したい場合のみです。
注意点として、電源マネージャが適切なイベントに対して systemd を inhibit しないと、systemd がシステムをサスペンドし、その後サスペンドから復帰すると今度は電源マネージャがシステムを再びサスペンドしてしまうという状況に陥る可能性があります。KDE、GNOME、Xfce、そして MATE の電源マネージャは、必要な inhibited コマンドを発行します。inhibited コマンドが発行されない場合 (acpid などを使って ACPI イベントを処理している場合)、Handle
オプションを ignore
に設定してください。systemd-inhibit(1) も参照してください。
xss-lock
xss-lock は systemd の suspend
、hibernate
、lock-session
、unlock-session
イベントで適切なアクションを実行します (ロッカーを実行し、ユーザがロッカーをアンロックまたは kill するまで待機する)。xss-lock は DPMS イベントにも反応し、それに応じてロッカーを実行したり kill したりします。
例えば、以下のコマンドを自動起動します:
$ xss-lock -- i3lock -n -i background_image.png &
サスペンドとハイバネート
systemd は、カーネルのネイティブなサスペンド/レジューム機能を使用して、サスペンド (suspend to RAM) を行うコマンドや、ハイバネートを行うコマンドを提供しています。また、サスペンド前や後の動作をカスタマイズするためのフックを追加する機構も存在しています。
systemctl suspend
は何も設定しなくても動くはずですが、あなたの環境で systemctl hibernate
を使うには 電源管理/サスペンドとハイバネート#ハイバネーション の指示に従う必要があります。
また、サスペンドとハイバネートを組み合わせたモードが 2 つ存在します:
systemctl hybrid-sleep
は、システムを RAM とディスクの両方にサスペンドします。なので、電源が完全に失われても、データ損失が発生しません。このモードは suspend to both とも呼ばれています。systemctl suspend-then-hibernate
は、最初は可能な限り長くシステムを RAM にサスペンドし、RTC アラームで復帰し、そしてハイバネートします。RTC アラームは systemd-sleep.conf(5) 内のHibernateDelaySec
で設定します。デフォルトの値は、システムのバッテリーレベルが 5% に下がるまでの推定された時間に設定されます。システムにバッテリーが存在しない場合は、デフォルトで2時間に設定されます。推定時間は、systemd-sleep.conf(5) 内のSuspendEstimationSec
によって指定された時間後のバッテリーレベルの変化から計算されます。SuspendEstimationSec
の時間後、システムは短い間サスペンドから復帰し、計測を行います (システムが手動でサスペンドから復帰された場合も、計測が行われます)。
サスペンドやハイバネートのリクエスト時にハイブリッドスリープを行う
サスペンドやハイバネートのリクエスト時にも、ハイブリッドスリープを常に行うように systemd を設定することができます。
サスペンドとハイバネートのデフォルトの動作は、/etc/systemd/sleep.conf.d/
内の .conf ファイルで設定することができます。両方の動作を ハイブリッドスリープ に設定するには:
/etc/systemd/sleep.conf.d/hybrid-sleep.conf
[Sleep] # suspend=hybrid-sleep SuspendMode=suspend SuspendState=disk # hibernate=hybrid-sleep HibernateMode=suspend HibernateState=disk
詳細は sleep.conf.d(5) man ページと linux カーネルの電源状態に関するドキュメントを参照してください。
サスペンドを無効化する
デバイスをサーバなどとして使用している場合、サスペンドは必要ないかもしれませんし、かえって望ましくない可能性もあります。 任意のスリープ状態を設定することができます:
/etc/systemd/sleep.conf.d/disable-suspend.conf
[Sleep] AllowSuspend=no AllowHibernation=no AllowSuspendThenHibernate=no AllowHybridSleep=no
スリープフック
サスペンド/リジュームのサービスファイル
サービスファイルを suspend.target、hibernate.target、sleep.target、hybrid-sleep.target、そして suspend-then-hibernate.target にフックすることで、サスペンド/ハイバネート前や後に行うアクションを設定できます。ユーザのアクションと root/システムのアクションを設定するには、別々のファイルを作成する必要があります。suspend@user
と resume@user
サービスを有効化してこれらをブート時に起動させてください。例:
/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 ExecStart=/usr/bin/sflock ExecStartPost=/usr/bin/sleep 1 [Install] WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit] Description=User resume actions After=suspend.target [Service] User=%I Type=simple ExecStart=/usr/local/bin/ssh-connect.sh [Install] WantedBy=suspend.target
root/システムのアクションの場合 (root-resume
と root-suspend
を有効化してこれらをブート時に起動させてください):
/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
/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/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
: 起動後、明示的に止められるまでサービスは常時 active とみなされます。StopWhenUnneeded=yes
: active 時、他のサービスから必要とされなくなった場合、サービスは停止されます。この例では、sleep.target が停止されるとこのサービスは停止されます。- sleep.target は suspend.target、hibernate.target、hybrid-sleep.target から呼ばれ、sleep.target 自身は StopWhenUnneeded サービスなので、タスクごとにフックが正しく起動・停止することが保証されています。
汎用のサービステンプレート
この例では、既存の systemd サービスを電源イベントにフックさせるために使用できるテンプレートサービスを作ります:[1]
/etc/systemd/system/sleep@.service
[Unit] Description=%I sleep hook Before=sleep.target StopWhenUnneeded=yes [Service] Type=oneshot RemainAfterExit=yes ExecStart=-/usr/bin/systemctl stop %i ExecStop=-/usr/bin/systemctl start %i [Install] WantedBy=sleep.target
次に、@
の後に既存の systemd サービスの basename を指定して、このテンプレートのインスタンスを有効化してください (つまり、sleep@service-file-basename.service
)。テンプレートに関する詳細は systemd.unit(5) § DESCRIPTION を参照してください。
/usr/lib/systemd/system-sleep のフック
systemd は /usr/lib/systemd/system-sleep/
内の全ての実行可能ファイルを実行するときに、2つの引数を渡します:
- 引数 1:
pre
かpost
。マシンがスリープしようとしているのか、復帰しようとしているのかによります。 - 引数 2:
suspend
かhibernate
かhybrid-sleep
。どれが行われようとしているのかによります。
systemd はスクリプトを (ひとつずつではなく) 並行に実行します。
カスタムスクリプトの出力は systemd-suspend.service か systemd-hibernate.service か systemd-hybrid-sleep.service によって記録されます。出力を見るには systemd の journalctl を使って下さい:
# journalctl -b -u systemd-suspend.service
カスタムスリープスクリプトの例:
/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
スクリプトを実行可能にするのを忘れないで下さい。
詳しくは systemd.special(7) や systemd-sleep(8) を見てください。
トラブルシューティング
フタのスイッチのアクションの遅延
短期間に連続してフタのスイッチが反応した場合、logind はドッキングを検出するために90秒までサスペンドを遅延します。[3] この遅延時間は systemd v220 から設定できるようになりました:[4]
/etc/systemd/logind.conf
... HoldoffTimeoutSec=30s ...
ノートパソコンをサスペンドする Fn キーが動作しない
logind.conf
をどう設定してもスリープボタンが動作しない場合 (ボタンを押しても syslog にメッセージすら表示されない)、おそらく logind がキーボードデバイスを監視していません。[5] 次のコマンドを実行してください:
# journalctl --grep="Watching system buttons"
すると以下のような表示がされます:
May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event2 (Power Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event3 (Sleep Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event4 (Video Bus)
キーボードデバイスがないことに気づいて下さい。したがってキーボードデバイスの ATTRS{name} を取得します [6]:
# udevadm info -a /dev/input/by-path/*-kbd
... KERNEL=="event0" ... ATTRS{name}=="AT Translated Set 2 keyboard"
カスタムの udev ルールを作成して、"power-switch" タグを追加してください:
/etc/udev/rules.d/70-power-switch-my.rules
ACTION=="remove", GOTO="power_switch_my_end" SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="AT Translated Set 2 keyboard", TAG+="power-switch" LABEL="power_switch_my_end"
systemd-udevd.service
を再起動し、udevadm trigger
を root として実行してルールを再読み込みし、そして systemd-logind.service
を再起動してください。
これで、syslog に Watching system buttons on /dev/input/event0
と表示されるようになるはずです。
A520I および B550I マザーボードで PC がスリープから復帰しない
A520i および B550i チップセットを搭載した一部のマザーボードでは、システムが完全にスリープ状態に入らない、またはスリープ状態から復帰しないことがあります。症状は、システムがスリープ状態に入り、マザーボード上の内部 LED または電源 LED が点灯したまま、モニターの電源が切れるというものです。その後、システムはこの状態から復帰することができず、ハードパワーオフが必要となります。AMD で同様の問題が発生した場合、まずシステムが完全にアップデートされていることを確認し、AMD マイクロコード パッケージがインストールされているかどうかをチェックしてください。
GPP0
で始まる行のステータスが有効になっていることを確認します:
$ cat /proc/acpi/wakeup
Device S-state Status Sysfs node GP12 S4 *enabled pci:0000:00:07.1 GP13 S4 *enabled pci:0000:00:08.1 XHC0 S4 *enabled pci:0000:0b:00.3 GP30 S4 *disabled GP31 S4 *disabled PS2K S3 *disabled GPP0 S4 *enabled pci:0000:00:01.1 GPP8 S4 *enabled pci:0000:00:03.1 PTXH S4 *enabled pci:0000:05:00.0 PT20 S4 *disabled PT24 S4 *disabled PT26 S4 *disabled PT27 S4 *disabled PT28 S4 *enabled pci:0000:06:08.0 PT29 S4 *enabled pci:0000:06:09.0
これが有効になっている場合は、次のコマンドを実行できます:
# echo GPP0 > /proc/acpi/wakeup
systemctl suspend
を実行してテストし、システムをスリープ状態にします。次に、数秒後にシステムを起動してみてください。うまくいく場合は、回避策を永続的にすることができます。systemd ユニットファイルを作成します。:
/etc/systemd/system/toggle-gpp0-to-fix-wakeup.service
[Unit] Description="Disable GPP0 to fix suspend issue" [Service] ExecStart=/bin/sh -c "/bin/echo GPP0 > /proc/acpi/wakeup" [Install] WantedBy=multi-user.target
新しく作成したユニットを daemon-reload および起動/有効化します。
ヒントとテクニック
ハイバネート専用のオンデマンドなスワップ
セットアップによっては、ハイバネートの時にだけスワップ領域をアクティブ化させ、復帰後に非アクティブ化させることが望ましい場合があります。
これは上記のフックを使って行うこともできますが、以下のようにスワップのユニット設定ファイル (systemd.swap(5) を参照) を直接使うこともできます:
/etc/systemd/system/path-to-swap.swap
[Unit] Before=systemd-hibernate.service StopWhenUnneeded=true [Swap] What=/path/to/swap Options=noauto [Install] RequiredBy=systemd-hibernate.service
注意点として、ユニットのファイル名はスワップデバイスのパスに対応していなければならず、さらに、RequiredBy=
が効果を持つにはユニットが有効化されていなければなりません。 (訳注: 例えば、スワップデバイスが /dev/sda5
にある場合、ユニットファイル名は dev-sda5.swap
としなければなりません。)
systemd-hibernate.service
ではなく hibernate.target
に依存させることも可能ですが、その場合、systemctl start systemd-hibernate.service
を直接実行しても機能しません。
注意点として、デスクトップ環境はハイバネートのオプションを表示しない可能性があり、systemctl hibernate
は機能しません。なぜなら、これらは systemd-logind
にクエリして利用可能な省電力モードを調べますが、systemd-logind
はスワップ領域がアクティブでない場合はハイバネーションが利用可能であると報告しないからです。
この問題は、SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1
環境変数を設定して systemd-logind
を開始することで回避できます。例えば、"ドロップイン" 設定ディレクトリ内で以下のようなファイルを作成します:
/etc/systemd/system/systemd-logind.service.d/disable-hibernation-swap-check.conf
[Service] Environment="SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"
省電力
このセクションは、カスタムスクリプトや udev ルールなどの省電力設定をの作成するためのリファレンスです。競合を避けるために、設定が他のユーティリティによって管理されていないことを確認してください。
コンピュータが AC 電源またはバッテリーで動作しているかに関わらず、ここに記載されているほとんど全ての機能には使用する価値があります。ここで挙げている機能のほとんどは、パフォーマンスへの影響は無視できるレベルであり、大抵、壊れているハードウェアやドライバのせいでデフォルトで有効化されていないだけです。電力の使用量を減らすことは発熱を減らすことでもあり、動的なオーバークロックによって、最近の Intel や AMD の CPU ではパフォーマンスの向上につながることもあります。
Intel HWP (Intel Hardware P-state) をサポートする CPU
HWP 対応プロセッサで利用可能なエネルギー設定は、default
、performance
、balance_performance
、balance_power
、power
です。
以下を実行することで、利用可能な設定を確認できます:
$ cat /sys/devices/system/cpu/cpufreq/policy?/energy_performance_available_preferences
以下のファイルを作成することで、より多くのエネルギーを節約するように設定できます:
/etc/tmpfiles.d/energy_performance_preference.conf
w /sys/devices/system/cpu/cpufreq/policy?/energy_performance_preference - - - - balance_power
詳細は systemd-tmpfiles(8) と tmpfiles.d(5) man ページを参照してください。
オーディオ
カーネル
デフォルトでは、オーディオの省電力機能はほとんどのドライバーで無効になっています。power_save
パラメータを設定することで有効にすることができます。アイドルモードに移行するまでの時間を秒数で指定します。1秒後にオーディオカードをアイドル状態にするには、Intel のサウンドカードの場合、以下のファイルを作成してください:
/etc/modprobe.d/audio_powersave.conf
options snd_hda_intel power_save=1
ac97 の場合は以下を使って下さい:
options snd_ac97_codec power_save=1
HDMI の音声出力を無効化することで、オーディの電力要件を下げることもできます。適切なカーネルモジュール (例: Intel のハードウェアの場合は snd_hda_codec_hdmi
) をブラックリスト化することで可能です。
PulseAudio
PulseAudio はデフォルトで、長時間アイドル状態になったオーディオソースを一時停止します。外部 USB マイクを使用する場合、録音がポップ音で開始されることがあります。回避策として、/etc/pulse/default.pa
の次の行をコメントアウトしてください:
load-module module-suspend-on-idle
その後、systemctl restart --user pulseaudio
で PulseAudio を再起動させてください。
バックライト
バックライトを見て下さい。
Bluetooth
Bluetooth を完全に無効化するには、btusb
と bluetooth
モジュールをブラックリストに入れてください。
一時的にだけ bluetooth をオフにするには、rfkill を使用します:
# rfkill block bluetooth
もしくは udev ルールを使って:
/etc/udev/rules.d/50-bluetooth.rules
# disable bluetooth SUBSYSTEM=="rfkill", ATTR{type}=="bluetooth", ATTR{state}="0"
ウェブカメラ
内蔵のウェブカメラを使わない場合、uvcvideo
モジュールをブラックリストに入れてください。
カーネルパラメータ
このセクションでは /etc/sysctl.d/
内の設定を使います。このディレクトリは、"カーネルの sysctl パラメータ用のドロップインディレクトリです"。詳細は、The New Configuration Files や、より詳しい sysctl.d(5) を見てください。
NMI watchdog の無効化
NMI watchdog は、カーネルパニックを引き起こすハードウェアのハングアップをキャッチするデバッグ機能です。システムによっては大量の割り込みが発生するため、消費電力の増加につながっていることがあります:
/etc/sysctl.d/disable_watchdog.conf
kernel.nmi_watchdog = 0
もしくは起動の初期で完全に無効化するにはカーネルラインに nmi_watchdog=0
を追加してください。
ライトバック時間
仮想メモリのダーティライトバック時間を増やすことでディスク I/O がまとめられて、断続的なディスクの書き込みが減って、消費電力が抑えられます。この値を60秒に設定するには (デフォルトは5秒です):
/etc/sysctl.d/dirty.conf
vm.dirty_writeback_centisecs = 6000
ジャーナルをサポートしているファイルシステム (ext4 や btrfs など) でジャーナルコミットでも同じことをするには、fstab でオプションとして commit=60
を使用します。
この値は、以下の Laptop Mode 設定の副作用として変更されてしまうことに注意してください。また、I/O パフォーマンスと省電力に影響を与える他のパラメータは sysctl#仮想メモリ を参照してください。
Laptop Mode
ラップトップモードの"ノブ"についてはカーネルドキュメントを見て下さい。"このノブの妥当な値は5秒です。"
/etc/sysctl.d/laptop.conf
vm.laptop_mode = 5
ネットワークインターフェイス
Wake-on-LAN は便利な機能ですが、利用しない場合はサスペンド中にマジックパケットが来るのを待つのに無駄な電力を消耗するだけです。Wake-on-LAN#udev ルールを調整することで、全てのイーサネットインターフェイスに対してこの機能を無効化することができます。iw を使って全てのワイヤレスインターフェイスで省電力を有効化するには:
/etc/udev/rules.d/81-wifi-powersave.rules
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wl*", RUN+="/usr/bin/iw dev $name set power_save on"
この設定ファイルの名前は重要です。Systemd の永続的なデバイス名を使用することで、上記のネットワークルールは、辞書順で 80-net-setup-link.rules
の後に来るので、ネットワークデバイスの名前が永続的な名前に変更 (例: wlan0
から wlp3s0
) された後で適用されます。RUN
のコマンドは、全てのルールが処理された後で実行され、永続的な名前 (マッチするデバイスは $name
で利用できます) を使用する必要があることに注意してください。
Intel ワイヤレスカード (iwlwifi)
iwlwifi
ドライバによる Intel ワイヤレスカードの追加の省電力機能は、適切なパラメータをカーネルモジュールに渡すことで有効化できます。/etc/modprobe.d/iwlwifi.conf
ファイルに以下の記述を追加することで、パラメータを永続化させることができます:
options iwlwifi power_save=1
以下のオプションは、レイテンシの中央値を増加させる可能性があります:
options iwlwifi uapsd_disable=0
5.4 より前のカーネルでは、以下のオプションを使用できますが、スループットの最大値を減少させる可能性があります:
options iwlwifi d0i3_disable=0
ワイヤレスカードによっては、以下の2つのオプションのうちいずれかが適用されます:
options iwlmvm power_scheme=3
options iwldvm force_cam=0
以下のコマンドで、どちらのモジュールが動作しているかを確認することで、どちらが関連しているかを確認できます:
# lsmod | grep '^iwl.vm'
これらの省電力オプションは実験的であり、システムを不安定にする可能性があることに注意してください。
バスパワーの管理
Active State Power Management
Wikipedia から:
- Active-state power management (ASPM) とは、PCI Express デバイスが完全にアクティブな状態にある時に電力を節約するための電源管理メカニズムです。主に、active-state link power management を介して行われます。つまり、PCI Express シリアルリンクは、トラフィックが存在しない時にパワーダウンされます。これは通常、ノート PC や他のモバイルインターネットデバイスでバッテリーの寿命を伸ばすために使用されます。
ASPM は、ハードウェアによってサポートされているかどうかに応じて、ブート時に有効化または無効化されます。以下のコマンドを root 権限で実行することで、サポートされているかどうかを確認できます:
# lspci -vv | grep 'ASPM.*abled;'
ASPM は BIOS によって管理されます。しばしば以下の理由によって無効化されることがあります [7]:
- BIOS が何らかの理由で ASPM を無効化した (コンフリクトが起こるから?)。
- PCIE が ASPM を必要とするが、L0s は任意である (なので、L0s は無効化され、L1 だけが有効化されるかもしれません)。
- ASPM 用に BIOS がプログラムされていない。
- BIOS にバグが存在する。
上記で ASPM がサポートされていないと報告されたが、ハードウェアが ASPM をサポートしていると思われる場合は、カーネルが ASPM を管理できるようにするために pcie_aspm=force
カーネルパラメータで ASPM を強制的に有効化できます。
現在のセッションで powersave
に調整するには次を実行してください (以下のコマンドは ASPM が有効になっていないと機能しません):
# echo powersave > /sys/module/pcie_aspm/parameters/policy
システムのブート時に特定の ASPM 状態 (例として powersave
) を有効化させるには、pcie_aspm.policy=powersave
をカーネルパラメータに追加してください。
以下を実行すると、利用可能な ASPM ポリシーと現在のデフォルトを取得できます:
$ cat /sys/module/pcie_aspm/parameters/policy
[default] performance powersave powersupersave
PCI Runtime Power Management
/etc/udev/rules.d/pci_pm.rules
SUBSYSTEM=="pci", ATTR{power/control}="auto"
上記のルールは未使用のデバイスを全てパワーダウンしますが、一部のデバイスが復帰しなくなってしまいます。サポートしていることが分かっているデバイスのみに対して Runtime Power Management を有効化するには、ベンダ ID とデバイス ID を使って、特定のデバイスにだけマッチするようにしてください (ID を入手するには lspci -nn
を使ってください):
/etc/udev/rules.d/pci_pm.rules
# whitelist for pci autosuspend SUBSYSTEM=="pci", ATTR{vendor}=="0x1234", ATTR{device}=="0x1234", ATTR{power/control}="auto"
または、PCI Runtime Power Management が機能しないデバイスを除外して、その他の全てのデバイスに対して有効化するには:
/etc/udev/rules.d/pci_pm.rules
# blacklist for pci runtime power management SUBSYSTEM=="pci", ATTR{vendor}=="0x1234", ATTR{device}=="0x1234", ATTR{power/control}="on", GOTO="pci_pm_end" SUBSYSTEM=="pci", ATTR{power/control}="auto" LABEL="pci_pm_end"
USB の自動サスペンド
Linux カーネルは USB デバイスが使用されていないときに USB デバイスを自動的にサスペンドさせることができます。これによって電力を相当カットできるときもありますが、USB の省電力機能に対応していない USB デバイスではおかしな挙動が起こる可能性もあります (特に USB マウスやキーボード)。ホワイトリストとブラックリストでフィルタリングする udev ルールを使うことで問題は軽減されます。
最も単純でおそらく役に立たない、全ての USB デバイスで自動サスペンドを有効にする例:
/etc/udev/rules.d/50-usb_power_save.rules
ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="auto"
自動サスペンドが動作するデバイスにだけ自動サスペンドを有効にするには、ベンダー ID とプロダクト ID でマッチングを行います (これらの ID を入手するには lsusb を使ってください):
/etc/udev/rules.d/50-usb_power_save.rules
# whitelist for usb autosuspend ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", ATTR{power/control}="auto"
もしくは、USB 自動サスペンドが使えないデバイスをブラックリストに入れて、他の全てのデバイスで自動サスペンドを有効にするには:
/etc/udev/rules.d/50-usb_power_save.rules
# blacklist for usb autosuspend ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", GOTO="power_usb_rules_end" ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="auto" LABEL="power_usb_rules_end"
自動サスペンドに入るデフォルトのアイドル遅延時間は usbcore
組み込みカーネルモジュールの autosuspend
パラメータによって制御されています。遅延時間をデフォルトの2秒から5秒に設定するには、以下のカーネルパラメータを追加してください:
usbcore.autosuspend=5
power/control
と同じように、power/autosuspend
属性を設定することで遅延時間はデバイスごとに細かく設定することができます。また、power/autosuspend
を -1 (つまり、自動サスペンドしない) に設定することで、自動サスペンドを無効化することができます:
/etc/udev/rules.d/50-usb_power_save.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", ATTR{power/autosuspend}="-1"
USB の電源管理に関する詳細は Linux カーネルドキュメントを見て下さい。
SATA Active Link Power Management
Linux 4.15 から、med_power_with_dipm
と呼ばれる新しい設定が存在しています。これは、Windows IRST ドライバ設定の動作と一致するものであり、最近の SSD や HDD ではデータの損失は発生しないはずです。(アイドル状態で) 1.0 から 1.5 ワットの節約になることもあります。これは、Linux 4.16 から Intel ベースのノート PC でデフォルトの設定になる予定です [8]。
現在の設定は /sys/class/scsi_host/host*/link_power_management_policy
で確認できます:
$ cat /sys/class/scsi_host/host*/link_power_management_policy
設定 | 説明 | 省電力効果 |
---|---|---|
max_performance | 現在のデフォルト | 無し |
medium_power | - | 約 1.0 ワット |
med_power_with_dipm | 推奨される設定 | 約 1.5 ワット |
min_power | 警告: データ損失の可能性あり | 約 1.5 ワット |
/etc/udev/rules.d/hd_power_save.rules
ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="med_power_with_dipm"
ハードディスクドライブ
設定できるドライブのパラメータについては hdparm#電源管理の設定 を見て下さい。
多数のプログラムがディスクに頻繁に書き込みをおこなう場合は省電力は効率的ではありません。全てのプログラムを調査して、いつどのようにプログラムがディスクに書き込むを行うのか調べるのがディスクの使用量を減らす道です。iotop を使えばどのプログラムがディスクに頻繁に書き込みしているかわかります。他のヒントは パフォーマンスの向上#ストレージデバイス を見て下さい。
noatime オプションを設定するなどの小さなことも馬鹿にできません。十分な RAM がある場合、swappiness を無効化したり制限することでディスクへの書き込みが減る可能性があります。
PowerChoice テクノロジーを搭載した Seagate ドライブの場合、hdparm から APM を設定するテクニックはうまく行きません。代わりに openseachestAUR パッケージをインストールしてください。例えば、以下のコマンドを使うことで、ドライブの EPC を完全に無効化することができます (X は実際のドライブレターに置き換えてください):
# openSeaChest_PowerControl --scan # openSeaChest_PowerControl -d /dev/sdX -i # openSeaChest_PowerControl -d /dev/sdX --showEPCSettings # openSeaChest_PowerControl -d /dev/sdX --EPCfeature disable # openSeaChest_PowerControl -d /dev/sdX --showEPCSettings
最後のコマンドでは、以下が出力されます:
========================================================================================== openSeaChest_PowerControl - openSeaChest drive utilities - NVMe Enabled Copyright (c) 2014-2023 Seagate Technology LLC and/or its Affiliates, All Rights Reserved openSeaChest_PowerControl Version: 3.3.1-4_1_1 X86_64 Build Date: Jul 4 2023 Today: Tue Jul 4 17:49:36 2023 User: root ========================================================================================== /dev/sdX - ST1000NM0008-2F2100 - ZFA19JG2 - SN02 - ATA ===EPC Settings=== * = timer is enabled C column = Changeable S column = Savable All times are in 100 milliseconds Name Current Timer Default Timer Saved Timer Recovery Time C S Idle A 0 *10 *10 1 Y Y Idle B 0 *1200 *1200 3 Y Y Idle C 0 6000 6000 16 Y Y Standby Z 0 9000 9000 46 Y Y
最初の列の 0 は、パーキングとスピンダウンが正常に無効化されたことを意味します。
ツールとスクリプト
スクリプトと udev ルールを使う
systemd ユーザーは systemctl suspend
や systemctl hibernate
でサスペンドとハイバネートを行うことができ、/etc/systemd/logind.conf
で acpi イベントを処理することができるので、pm-utils と acpid を削除するということに興味を引かれるかもしれません。systemd が行えないことがたったひとつだけ存在します (systemd-204 現在): システムが AC 電源で動作しているのか、バッテリーで動作しているのかで条件分岐を行う電源管理です。このギャップをなくすには、AC アダプタが抜き差しされたときにスクリプトを実行する udev ルールを作成します:
/etc/udev/rules.d/powersave.rules
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/path/to/your/script true" SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/path/to/your/script false"
powersave スクリプトのサンプル:
- ftw (パッケージ: ftw-gitAUR)
- powersave
- throttlectl (throttlectlAUR)
上記の udev ルールはちゃんと動作するはずですが、電源設定がサスペンドやハイバネートをした後に更新されない場合、以下の内容で /usr/lib/systemd/system-sleep/
にスクリプトを追加してください:
/usr/lib/systemd/system-sleep/00powersave
#!/bin/sh case $1 in pre) /path/to/your/script false ;; post) if cat /sys/class/power_supply/AC0/online | grep 0 > /dev/null 2>&1 then /path/to/your/script true else /path/to/your/script false fi ;; esac exit 0
忘れずに実行可能属性を付与してください。
電源設定の表示
以下のスクリプトは USB や PCI デバイスの電源設定などのプロパティを表示します。全ての設定を見るには root 権限が必要なので注意して下さい。
#!/bin/bash for i in $(find /sys/devices -name "bMaxPower") do busdir=${i%/*} busnum=$(<$busdir/busnum) devnum=$(<$busdir/devnum) title=$(lsusb -s $busnum:$devnum) printf "\n\n+++ %s\n -%s\n" "$title" "$busdir" for ff in $(find $busdir/power -type f ! -empty 2>/dev/null) do v=$(cat $ff 2>/dev/null|tr -d "\n") [[ ${#v} -gt 0 ]] && echo -e " ${ff##*/}=$v"; v=; done | sort -g; done; printf "\n\n\n+++ %s\n" "Kernel Modules" for mod in $(lspci -k | sed -n '/in use:/s,^.*: ,,p' | sort -u) do echo "+ $mod"; systool -v -m $mod 2> /dev/null | sed -n "/Parameters:/,/^$/p"; done
ユーザにシャットダウンを許可する
ボタンと蓋スイッチのイベント
サスペンド、電源オフ、そしてハイバネートのボタンのイベントと、蓋を閉じた時のイベントは、#ACPI イベント で説明されているように logind によって処理されます。
systemd-logind を使う
polkit を使用している場合、非リモートセッションのユーザは、セッションが壊れていない限り、電源関連のコマンドを発行することができます。
セッションがアクティブであることを確認するには:
$ loginctl show-session $XDG_SESSION_ID --property=Active
アクティブであるならば、ユーザはコマンドラインで systemctl のコマンドを使用したり、メニューに追加したりできます:
$ systemctl poweroff $ systemctl reboot
systemctl suspend
や systemctl hibernate
といった他のコマンドも使用できます。systemctl(1) の System Commands セクションを参照してください。
sudo を使う
sudo をインストールし、sudo 権限をユーザに与えてください。sudo 権限が与えられたユーザは、sudo systemctl
コマンド (例: sudo systemctl poweroff
、sudo systemctl reboot
、sudo systemctl suspend
、sudo systemctl hibernate
) を使用できるようになります。systemctl(1) の System Commands セクションを参照してください。
sudo 権限の無いユーザ
ユーザにシャットダウンコマンドのみを使用できるようにし、sudo 権限を与えないようにする必要がある場合、visudo
コマンドを root として使って /etc/sudoers
の末尾に以下を追加してください。user の部分は適切なユーザ名に、hostname の部分はマシンのホスト名に置き換えてください。
user hostname =NOPASSWD: /usr/bin/systemctl poweroff,/usr/bin/systemctl halt,/usr/bin/systemctl reboot
ここで設定したユーザは、sudo systemctl poweroff
でシャットダウンを、sudo systemctl reboot
で再起動を行うことができるようになります。システムをシャットダウンしたいユーザは、sudo systemctl halt
も使用できます。パスワードのプロンプトを表示させたくない場合は、NOPASSWD:
タグを使用してください。