Linux Kernel Power Management

Linux カーネル電力管理: 包括的技術ガイド


ドキュメントバージョン: 1.0 最終更新日: 2026年4月 対象読者: Linuxカーネル開発者、システム管理者、SREエンジニア、組み込みシステムエンジニア カーネルバージョン: 6.x系


目次

  1. Linux カーネル電力管理の概要
  2. ACPI サブシステム
  3. システムスリープ状態
  4. サスペンドとレジューム
  5. ハイバネーション
  6. ランタイムPMフレームワーク
  7. CPU周波数スケーリング (cpufreq)
  8. CPU周波数ガバナー
  9. CPUアイドル状態 (cpuidle)
  10. Intel P-StatesとAMD P-Statesドライバ
  11. エネルギー考慮スケジューリング (EAS)
  12. サーマル管理
  13. デバイス電力管理
  14. PCI電力管理
  15. USB電力管理
  16. パワーキャッピング (Intel RAPL)
  17. バッテリーとUPS管理
  18. レギュレータフレームワーク
  19. ラップトップとサーバーの電力管理
  20. 電力管理ツール
  21. ベストプラクティスとトラブルシューティング
  22. 参考文献

1. Linux カーネル電力管理の概要

電力管理はLinuxカーネルにおいて最も重要なサブシステムの一つであり、モバイルデバイスのバッテリー寿命、データセンターの電力コスト、熱挙動、ハードウェアの寿命に直接影響します。Linuxカーネルは、個々のデバイスドライバからシステム全体のスリープ状態まで、階層的でモジュール化されたアプローチで電力管理を提供しています。

1.1 電力管理が重要な理由

現代のコンピューティング環境において、電力管理は以下の重要な機能を果たします:

  • コスト削減: データセンターは膨大な電力を消費します。10万台のサーバーフリート全体で5%の電力効率改善でも、年間数百万ドルの節約になります。
  • 熱制御: 消費電力は直接的に発熱につながります。効果的な電力管理により、サーマルスロットリングやハードウェア損傷を防止できます。
  • バッテリー寿命: ラップトップ、タブレット、組み込みデバイスにおいて、電力管理は使用可能なバッテリー寿命を直接決定します。
  • 環境負荷: 消費電力の削減は、カーボンフットプリントの縮小を意味します。
  • ハードウェア寿命: より低い温度と電圧で動作するコンポーネントは、より長い寿命を持つ傾向があります。

1.2 アーキテクチャ概要

Linuxカーネルの電力管理アーキテクチャは、いくつかの層で構成されています:

+---------------------------------------------------------------+
|                  ユーザー空間アプリケーション                      |
|  (powertop, tlp, thermald, cpupower, systemd, upower)        |
+---------------------------------------------------------------+
|                  sysfs / procfs インターフェース                  |
|  (/sys/power, /sys/devices/.../power, /sys/class/thermal)     |
+---------------------------------------------------------------+
|              カーネル電力管理フレームワーク                        |
|  +-------------------+  +------------------+  +--------------+|
|  | システムスリープ     |  | ランタイムPM       |  | cpufreq      ||
|  | (サスペンド/休止)    |  | (デバイス単位)     |  | (CPU周波数)  ||
|  +-------------------+  +------------------+  +--------------+|
|  +-------------------+  +------------------+  +--------------+|
|  | cpuidle           |  | サーマル管理       |  | 電源供給      ||
|  | (C-states)        |  | (ゾーン/冷却)     |  | (バッテリー)  ||
|  +-------------------+  +------------------+  +--------------+|
|  +-------------------+  +------------------+  +--------------+|
|  | レギュレータFW     |  | パワーキャッピング  |  | クロックFW   ||
|  | (電圧/電流)        |  | (RAPL)           |  | (clk_*)      ||
|  +-------------------+  +------------------+  +--------------+|
+---------------------------------------------------------------+
|              プラットフォーム / バス固有ドライバ                   |
|  (ACPI, PCI PM, USB PM, platform_driver, i2c_driver等)       |
+---------------------------------------------------------------+
|                    ハードウェア / ファームウェア                   |
|  (CPU, チップセット, BIOS/UEFI, EC, 電圧レギュレータ, ファン)    |
+---------------------------------------------------------------+

1.3 主要なカーネル設定オプション

Linuxカーネルで包括的な電力管理サポートを有効にするための基本的なKconfigオプション:

# コア電力管理
CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_PM_DEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_PM_SLEEP_DEBUG=y

# ACPIサポート
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_AC=m
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_CPPC_LIB=y

# CPU周波数スケーリング
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y

# CPUアイドル
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_GOV_MENU=y
CONFIG_CPU_IDLE_GOV_TEO=y

# Intel/AMD固有
CONFIG_X86_INTEL_PSTATE=y
CONFIG_X86_AMD_PSTATE=y
CONFIG_INTEL_RAPL=m

# サーマル
CONFIG_THERMAL=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
CONFIG_INTEL_PCH_THERMAL=m

# サスペンド/ハイバネーション
CONFIG_SUSPEND=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""

# ランタイムPM
CONFIG_PM_RUNTIME=y  # (最新カーネルではCONFIG_PMに含まれる)

# 電源供給
CONFIG_POWER_SUPPLY=y
CONFIG_REGULATOR=y

1.4 sysfs電力管理インターフェース

電力管理の主要なユーザー空間インターフェースはsysfsを通じて提供されます:

# システム全体の電力管理
/sys/power/
    state           # 利用可能なスリープ状態と現在の状態
    mem_sleep       # メモリスリープモード (s2idle, shallow, deep)
    disk            # ハイバネーションモード (platform, shutdown, reboot, suspend)
    pm_async        # 非同期サスペンド/レジューム (0または1)
    pm_debug_messages   # PMデバッグメッセージ
    wakeup_count    # ウェイクアップイベントカウンター

# デバイス単位の電力管理
/sys/devices/.../power/
    control         # auto または on (ランタイムPM制御)
    runtime_status  # active, suspended, suspending, resuming, error
    runtime_active_time      # アクティブ時間
    runtime_suspended_time   # サスペンド時間
    autosuspend_delay_ms     # 自動サスペンド遅延(ミリ秒)
    wakeup          # enabled または disabled
    wakeup_count    # ウェイクアップ回数

2. ACPI サブシステム

2.1 ACPIの概要

ACPI (Advanced Configuration and Power Interface) は、オペレーティングシステム、プラットフォームファームウェア (BIOS/UEFI)、ハードウェア間のハードウェア抽象化層を定義するオープン標準です。LinuxにおけるACPIサブシステムは最大かつ最も複雑なコンポーネントの一つであり、以下を担当します:

  • システム電力状態管理 (スリープ、ウェイク、シャットダウン)
  • デバイスの列挙と設定
  • サーマルゾーン管理
  • バッテリーとACアダプターの監視
  • プロセッサの電力とパフォーマンス管理
  • プラットフォームイベント処理 (リッドスイッチ、電源ボタン等)

2.2 LinuxにおけるACPIアーキテクチャ

+------------------------------------------+
|           ユーザー空間                      |
|   (acpid, acpi_listen, upower)           |
+------------------------------------------+
|         /proc/acpi  /sys/firmware/acpi    |
+------------------------------------------+
|      ACPIサブシステム (drivers/acpi/)      |
|  +------------+  +--------------------+  |
|  | ACPIバス    |  | ACPIインタプリタ     |  |
|  | ドライバ     |  | (AML実行)          |  |
|  +------------+  +--------------------+  |
|  +------------+  +--------------------+  |
|  | ACPI EC    |  | ACPIサーマル        |  |
|  | ドライバ     |  | ドライバ            |  |
|  +------------+  +--------------------+  |
|  +------------+  +--------------------+  |
|  | ACPI電源    |  | ACPIプロセッサ       |  |
|  | ドライバ     |  | ドライバ            |  |
|  +------------+  +--------------------+  |
+------------------------------------------+
|        ACPIテーブル (ファームウェアから)     |
|  DSDT, SSDT, FADT, MADT, MCFG等         |
+------------------------------------------+
|           プラットフォームファームウェア      |
|          (BIOS / UEFI)                    |
+------------------------------------------+

2.3 ACPIテーブル

ACPIテーブルはプラットフォームファームウェアによって提供されるデータ構造です。ハードウェア構成を記述し、OSがプラットフォーム固有のハードウェアと対話するための実行可能コード (AML - ACPI Machine Language) を提供します。

電力管理に関連する主要なACPIテーブル:

テーブル名称目的
DSDTDifferentiated System Description Tableデバイス設定用AMLコードを含むメインテーブル
SSDTSecondary System Description Table補助的なAMLコード
FADTFixed ACPI Description Table固定ハードウェアレジスタ、PMタイマー、スリープ制御
MADTMultiple APIC Description Table割り込みコントローラ情報
DMARDMA Remapping TableIOMMU設定
HPETHigh Precision Event Timer Tableタイマーハードウェア

ACPIテーブルの調査

# 全ACPIテーブルの一覧
ls /sys/firmware/acpi/tables/

# ACPIテーブルのダンプ (acpica-tools / iaslが必要)
sudo acpidump > acpi_tables.dat
acpixtract -a acpi_tables.dat
iasl -d DSDT.dat    # DSDTをASLソースに逆コンパイル

# 特定テーブル情報の表示
sudo cat /sys/firmware/acpi/tables/FACP | hexdump -C | head -50

# カーネルのACPIサポートを確認
dmesg | grep -i acpi

# ACPI名前空間
ls /sys/firmware/acpi/
ls /sys/bus/acpi/devices/

2.4 ACPIイベントと通知

ACPIは様々なシステム変更に対してイベントを生成します。これらのイベントはACPIイベントインターフェースを通じてユーザー空間に配信されます:

# ACPIイベントのリアルタイム監視
acpi_listen

# 一般的なイベント:
# button/power PBTN 00000080 00000000     (電源ボタン押下)
# button/lid LID close                     (リッドクローズ)
# button/lid LID open                      (リッドオープン)
# ac_adapter ACPI0003:00 00000080 00000001 (AC接続)
# battery BAT0 00000080 00000001           (バッテリー状態変化)
# thermal_zone TZ0 00000081 00000000       (サーマルトリップ)

# acpidイベントハンドラの設定
ls /etc/acpi/events/
cat /etc/acpi/events/powerbtn
# event=button/power
# action=/etc/acpi/actions/powerbtn.sh

2.5 ACPI エンベデッドコントローラ (EC)

エンベデッドコントローラはマザーボード上のマイクロコントローラで、特にラップトップにおいて低レベルのハードウェア制御を担当します:

# EC情報
dmesg | grep -i "ec "
# [    0.532108] ACPI: EC: EC started
# [    0.532109] ACPI: EC: interrupt blocked

# EC GPE (General Purpose Event)
cat /sys/firmware/acpi/interrupts/gpe*

# ECオペレーションのデバッグ
echo 1 > /sys/module/acpi/parameters/aml_debug_output

2.6 ACPIプラットフォームプロファイル

最新のシステムでは、電力/パフォーマンスのトレードオフを調整するプラットフォームプロファイルをサポートしています:

# 利用可能なプロファイルと現在のプロファイルを確認
cat /sys/firmware/acpi/platform_profile_choices
# low-power balanced performance

cat /sys/firmware/acpi/platform_profile
# balanced

# プロファイルの変更
echo "performance" | sudo tee /sys/firmware/acpi/platform_profile
echo "low-power" | sudo tee /sys/firmware/acpi/platform_profile

2.7 ACPIウェイクアップソース

# ウェイクアップ対応デバイスの一覧
cat /proc/acpi/wakeup
# Device  S-state   Status   Sysfs node
# PCI0      S3    *enabled   no-bus:pci0000:00
# USB0      S3    *enabled   pci:0000:00:14.0
# LID0      S3    *enabled   platform:PNP0C0D:00
# PWRB      S3    *enabled   platform:PNP0C0C:00

# デバイスのウェイクアップ機能の切り替え
echo "USB0" | sudo tee /proc/acpi/wakeup

# sysfsによるデバイス単位のウェイクアップ制御
echo "enabled" | sudo tee /sys/devices/pci0000:00/0000:00:14.0/power/wakeup
echo "disabled" | sudo tee /sys/devices/pci0000:00/0000:00:14.0/power/wakeup

2.8 ACPIカーネルパラメータ

# 重要なACPI関連カーネルコマンドラインパラメータ
acpi=off            # ACPIを完全に無効化
acpi=force          # BIOSの日付が古くてもACPIを強制
acpi=noirq          # IRQルーティングにACPIを使用しない
acpi=strict         # ACPI仕様に違反するプラットフォームに対して厳格に
acpi_osi=Linux      # ファームウェアにLinuxであることを通知
acpi_osi=!Windows2020  # _OSI応答からWindows 2020を除去
acpi_backlight=vendor   # ベンダー固有のバックライトドライバを使用
acpi.debug_layer=0xFFFFFFFF    # 全ACPIデバッグレイヤーを有効化
acpi.debug_level=0x2           # デバッグレベルの設定

# GRUB設定例
# /etc/default/grub を編集:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash acpi_osi=Linux"

3. システムスリープ状態

3.1 ACPI定義のスリープ状態

ACPI仕様は、異なるレベルの省電力を表すいくつかのシステムスリープ状態(S状態)を定義しています:

状態名称説明省電力復帰時間コンテキスト保持
S0Workingシステム完全稼働なしN/A全て
S0ixModern Standby低電力アイドル(コネクテッドスタンバイ)< 1秒全て(DRAM内)
S1Power On SuspendCPU実行停止、キャッシュフラッシュ< 5秒CPU, DRAM
S2(ほとんど未使用)CPU電源オフ、DRAMリフレッシュ< 5秒DRAMのみ
S3Suspend-to-RAMほとんどのHW電源オフ、DRAMリフレッシュ1-5秒DRAMのみ
S4Hibernate全HW電源オフ、状態をディスクに保存非常に高10-30秒ディスクイメージ
S5Soft Offシステム電源オフ、PSUがスタンバイ電力供給最大フルブートなし

3.2 S0 - ワーキング状態

S0 (ワーキング) 状態では、システムは完全に稼働しています。このレベルでの電力管理は以下に焦点を当てます:

  • CPU周波数スケーリング (P-states)
  • CPUアイドル状態 (C-states)
  • デバイスランタイム電力管理
  • サーマル管理

3.3 S0ix - Modern Standby (S2idle)

Modern Standby (S0ix、Connected Standby、またはLinuxにおけるs2idleとも呼ばれる) は、最新のプラットフォームでS3を大きく置き換えた低電力アイドル状態です:

# s2idleが利用可能か確認
cat /sys/power/mem_sleep
# s2idle [deep]      -- 両方利用可能、deepがデフォルト
# [s2idle] deep      -- 両方利用可能、s2idleがデフォルト
# [s2idle]           -- s2idleのみ利用可能

# s2idleをサスペンドに使用
echo s2idle | sudo tee /sys/power/mem_sleep
echo mem | sudo tee /sys/power/state

# S0ix滞留カウンター (Intelプラットフォーム)
cat /sys/kernel/debug/pmc_core/slp_s0_residency_usec
cat /sys/kernel/debug/pmc_core/substate_residencies

3.4 S3 - Suspend-to-RAM

S3 (Suspend-to-RAM、Linuxでは"deep"スリープとも呼ばれる) は従来のサスペンドメカニズムです:

# ディープスリープの設定
echo deep | sudo tee /sys/power/mem_sleep

# サスペンドの実行
echo mem | sudo tee /sys/power/state

# 代替方法
systemctl suspend

# rtcwakeによるタイマーウェイクアップ
sudo rtcwake -m mem -s 3600  # 1時間後に復帰するサスペンド
sudo rtcwake -m mem -t $(date +%s -d "tomorrow 06:00")  # 午前6時に復帰

S3中のメモリレイアウト

S3サスペンド中:
+----------------------------------+
|  DRAM (セルフリフレッシュモード)     |
|  +----------------------------+  |
|  | カーネルイメージとデータ       |  |
|  | プロセスメモリ                |  |
|  | ページキャッシュ              |  |
|  | デバイス状態スナップショット    |  |
|  | CPUレジスタスナップショット     |  |
|  +----------------------------+  |
+----------------------------------+
|  その他全て電源オフ:               |
|  - CPU (電源なし)                 |
|  - GPU (電源なし)                 |
|  - PCIeデバイス (電源なし)        |
|  - USBデバイス (選択的)           |
|  - ディスプレイ (オフ)            |
|  - ファン (オフ)                  |
+----------------------------------+
アクティブなもの: RAMリフレッシュ, RTC, ウェイクアップソース
消費電力: 約1-3ワット (ラップトップ)

3.5 S4 - ハイバネーション (Suspend-to-Disk)

ハイバネーションはシステム全体の状態をスワップパーティションまたはファイルに保存し、完全に電源オフにします:

# ハイバネーションの可用性を確認
cat /sys/power/disk
# [platform] shutdown reboot suspend test_resume

# ハイバネーションの実行
echo disk | sudo tee /sys/power/state

# 代替方法
systemctl hibernate

# ハイブリッドサスペンド (まずサスペンド、バッテリー低下時にハイバネーション)
systemctl hybrid-sleep
systemctl suspend-then-hibernate

# ハイバネーションモードの設定
echo platform | sudo tee /sys/power/disk   # ACPIプラットフォーム方式
echo shutdown | sudo tee /sys/power/disk    # ハイバネーション後に電源オフ
echo reboot | sudo tee /sys/power/disk      # ハイバネーション後に再起動

# ハイバネーション用のスワップ設定
# /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/sda2"
# スワップファイルの場合:
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/sda2 resume_offset=2048"

4. サスペンドとレジューム

4.1 サスペンドプロセスの概要

Linuxのサスペンドプロセスは、明確に定義されたフェーズのシーケンスに従います。このフローを理解することは、サスペンド/レジュームの問題をデバッグする際に不可欠です。

ユーザー空間              カーネル                    ハードウェア
    |                          |                            |
    | echo mem > /sys/power/state                           |
    |------------------------->|                            |
    |                          | ユーザー空間プロセスを       |
    |                          | フリーズ                    |
    |                          |                            |
    |                          | デバイスをサスペンド          |
    |                          | (late, noirqフェーズ)       |
    |                          |                            |
    |                          | 非ブートCPUを無効化          |
    |                          |                            |
    |                          | プラットフォームスリープに入る  |
    |                          |--------------------------->|
    |                          |                            |
    |                    (システムスリープ中)                   |
    |                          |                            |
    |                          | <--- ウェイクアップイベント    |
    |                          |                            |
    |                          | 非ブートCPUを有効化          |
    |                          |                            |
    |                          | デバイスをレジューム          |
    |                          | (noirq, earlyフェーズ)      |
    |                          |                            |
    |                          | ユーザー空間プロセスを解凍    |
    |                          |                            |
    | <-----------------------|                             |
    | write()から復帰          |                             |

4.2 詳細なサスペンドフェーズ

カーネルのサスペンドプロセスは以下のフェーズを経ます:

フェーズ1: 準備
    - PM通知チェーンへの通知 (PM_SUSPEND_PREPARE)
    - ユーザー空間プロセスのフリーズ (freezer)
    - カーネルスレッドのフリーズ (PF_NOFREEZEマーク付きを除く)

フェーズ2: サスペンド
    - デバイスサスペンドコールバック (順序通り):
        a) dev->pm->prepare()        -- サスペンド前の準備
        b) dev->pm->suspend()        -- メインサスペンドハンドラ
        c) dev->pm->suspend_late()   -- 遅延サスペンド (IRQ処理後)
        d) dev->pm->suspend_noirq()  -- 最終サスペンド (IRQ無効)

フェーズ3: プラットフォーム進入
    - 非ブートCPUの無効化
    - システム割り込みの無効化
    - プラットフォーム固有のスリープ進入 (ACPI SLP_TYP)
    - CPUが低電力状態に入る

フェーズ4: レジューム (逆順)
    - プラットフォームウェイクアップ
    - システム割り込みの有効化
    - 非ブートCPUの有効化
    - デバイスレジュームコールバック:
        a) dev->pm->resume_noirq()
        b) dev->pm->resume_early()
        c) dev->pm->resume()
        d) dev->pm->complete()
    - プロセスの解凍
    - PM通知チェーンへの通知 (PM_POST_SUSPEND)

4.3 デバイスサスペンド/レジュームコールバックの実装

/* デバイスドライバPMコールバックの例 */
#include <linux/pm.h>
#include <linux/pm_runtime.h>

static int mydevice_suspend(struct device *dev)
{
    struct mydevice_data *data = dev_get_drvdata(dev);

    /* デバイス状態の保存 */
    data->saved_reg1 = readl(data->regs + REG1_OFFSET);
    data->saved_reg2 = readl(data->regs + REG2_OFFSET);

    /* デバイス割り込みの無効化 */
    writel(0, data->regs + IRQ_ENABLE_OFFSET);

    /* クロックの無効化 */
    clk_disable_unprepare(data->clk);

    dev_dbg(dev, "デバイスをサスペンドしました\n");
    return 0;
}

static int mydevice_resume(struct device *dev)
{
    struct mydevice_data *data = dev_get_drvdata(dev);
    int ret;

    /* クロックの再有効化 */
    ret = clk_prepare_enable(data->clk);
    if (ret) {
        dev_err(dev, "クロックの有効化に失敗: %d\n", ret);
        return ret;
    }

    /* デバイス状態の復元 */
    writel(data->saved_reg1, data->regs + REG1_OFFSET);
    writel(data->saved_reg2, data->regs + REG2_OFFSET);

    /* 割り込みの再有効化 */
    writel(data->irq_mask, data->regs + IRQ_ENABLE_OFFSET);

    dev_dbg(dev, "デバイスをレジュームしました\n");
    return 0;
}

static const struct dev_pm_ops mydevice_pm_ops = {
    .suspend        = mydevice_suspend,
    .resume         = mydevice_resume,
    .suspend_noirq  = mydevice_suspend_noirq,
    .resume_noirq   = mydevice_resume_noirq,
    .freeze         = mydevice_suspend,     /* ハイバネーション・フリーズ */
    .thaw           = mydevice_resume,       /* ハイバネーション・解凍 */
    .restore        = mydevice_resume,       /* ハイバネーション・復元 */
    .poweroff       = mydevice_suspend,      /* ハイバネーション・電源オフ */
    SET_RUNTIME_PM_OPS(mydevice_runtime_suspend,
                       mydevice_runtime_resume, NULL)
};

4.4 サスペンド/レジュームのデバッグ

# PMデバッグメッセージの有効化
echo 1 | sudo tee /sys/power/pm_debug_messages

# PMタイミング情報の有効化
echo 1 | sudo tee /sys/power/pm_print_times

# デバッグ情報付きサスペンド
echo platform | sudo tee /sys/power/pm_test  # プラットフォーム操作テスト
echo devices | sudo tee /sys/power/pm_test   # デバイスサスペンド/レジュームテスト
echo freezer | sudo tee /sys/power/pm_test   # プロセスフリーズテスト
echo none | sudo tee /sys/power/pm_test      # 通常サスペンド (デフォルト)

# サスペンド/レジュームタイミングの分析
sudo bash -c 'echo 1 > /sys/power/pm_print_times'
sudo bash -c 'echo mem > /sys/power/state'
dmesg | grep -E "\[suspend\]|\[resume\]|call |PM:" | tail -50

# sleepgraph (analyze_suspend.py) の使用
sudo sleepgraph -m mem -rtcwake 15
# サスペンド/レジュームタイミングの詳細なHTMLレポートを作成

# 一般的なサスペンド/レジューム問題
# デバイスのサスペンド失敗
dmesg | grep -E "PM: Device .* failed to suspend"

# スリープを妨げるウェイクアップソース
cat /sys/kernel/debug/wakeup_sources

# フリーザーをブロックするプロセス
dmesg | grep "Freezing of tasks"
ps aux | awk '$8 ~ /D/'

5. ハイバネーション

5.1 ハイバネーションの概要

ハイバネーション (S4) はシステム全体の状態を永続ストレージに保存し、完全に電源オフにします。システムが再び電源オンになると、保存された状態が復元され、ユーザーは中断したところから正確に続けることができます。

Linuxは2つの主要なハイバネーション実装をサポートしています:

  1. swsusp (カーネル内): 標準的なカーネルハイバネーションメカニズム
  2. uswsusp (ユーザー空間サスペンド): より柔軟性を提供するユーザー空間実装

5.2 swsusp (カーネル内ハイバネーション)

swsuspの動作原理

ハイバネーションプロセス:
1. 全ユーザープロセスとカーネルスレッドをフリーズ
2. 全メモリのスナップショットを作成 (スナップショットページの割り当て)
3. スナップショットイメージをスワップパーティション/ファイルに書き込み
4. シャットダウンのためプラットフォームファームウェアを呼び出し (ACPI S4または電源オフ)

レジュームプロセス:
1. システムが通常通りブート (ブートローダー -> カーネル)
2. カーネルがコマンドラインのresume=パラメータを検出
3. カーネルがスワップからスナップショットイメージを読み込み
4. アトミック復元: 全メモリページを復元
5. 全プロセスとデバイスが復元
6. スリープからの復帰のようにシステムが続行

設定

# 1. スワップパーティションが十分な大きさであることを確認 (RAM以上を推奨)
swapon --show
# NAME      TYPE       SIZE   USED PRIO
# /dev/sda2 partition   16G   0B   -2

# 2. レジューム用のカーネルコマンドラインを設定
# /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/sda2"
sudo update-grub

# スワップファイルの場合 (パーティションではなく):
# スワップファイルのオフセットを見つける
sudo filefrag -v /swapfile | head -5

# resume_offsetはphysical_offsetの値
GRUB_CMDLINE_LINUX_DEFAULT="resume=/dev/sda2 resume_offset=2097152"

# 3. initramfsの設定 (Debian/Ubuntu)
echo "RESUME=/dev/sda2" | sudo tee /etc/initramfs-tools/conf.d/resume
sudo update-initramfs -u

# 4. ハイバネーションのテスト
sudo systemctl hibernate

# 5. ハイバネーションイメージサイズの確認
cat /sys/power/image_size
# デフォルトは利用可能RAMの2/5
# カスタムイメージサイズの設定 (小さい=高速だが失敗の可能性)
echo $((1024*1024*1024*4)) | sudo tee /sys/power/image_size  # 4 GB

5.3 uswsusp (ユーザー空間ソフトウェアサスペンド)

uswsuspはハイバネーションのロジックをユーザー空間に移し、以下の利点を提供します:

  • サスペンド/レジューム中のグラフィカルな進捗表示
  • ハイバネーションイメージの暗号化
  • より良いエラーハンドリング
  • LZF圧縮サポート
# uswsuspのインストール
sudo apt install uswsusp  # Debian/Ubuntu

# /etc/uswsusp.confの設定
cat > /etc/uswsusp.conf << 'EOF'
# /etc/uswsusp.conf
# スナップショットイメージを書き込むデバイス
resume device = /dev/sda2

# 圧縮
compress = y

# 暗号化
encrypt = y

# イメージサイズ (0 = 自動)
image size = 0

# シャットダウン方法: platform, shutdown, または reboot
shutdown method = platform
EOF

# uswsuspを使用したハイバネーション
sudo s2disk

# uswsuspを使用したレジューム (initramfsから呼び出し)
sudo s2ram    # uswsuspを使用したSuspend to RAM

5.4 サスペンド後ハイバネーション

このハイブリッドアプローチは、まずRAMにサスペンドし、タイムアウト後にハイバネーションします:

# systemd設定
# /etc/systemd/sleep.conf
[Sleep]
AllowSuspend=yes
AllowHibernation=yes
AllowSuspendThenHibernate=yes
AllowHybridSleep=yes
SuspendMode=suspend
SuspendState=mem
HibernateMode=platform
HibernateState=disk
HibernateDelaySec=3600       # サスペンド1時間後にハイバネーション
SuspendEstimationSec=3600    # バッテリー推定間隔

# suspend-then-hibernateの実行
sudo systemctl suspend-then-hibernate

6. ランタイムPMフレームワーク

6.1 概要

ランタイムPMは、システム全体をスリープさせることなく、使用されていない個々のデバイスの電源をオフにできるフレームワークです。これは以下の用途で特に重要です:

  • 通常動作中のバッテリー寿命の延長
  • 発熱の削減
  • 長期間アイドル状態になる可能性のあるデバイスのサポート

6.2 ランタイムPM状態

                     pm_runtime_get_sync()
        +----------->  ACTIVE  <-----------+
        |            (usage > 0)            |
        |                |                  |
        |     pm_runtime_put_autosuspend()  |
        |                |                  |
        |                v                  |
        |           SUSPENDING              |
        |      (->runtime_suspend())        |
        |                |                  |
        |                v                  |
        |           SUSPENDED               |
        |        (デバイス電源オフ)            |
        |                |                  |
        |     pm_runtime_get_sync()         |
        |                |                  |
        |                v                  |
        +---        RESUMING                |
               (->runtime_resume())  -------+

6.3 ランタイムPM API

/* デバイスドライバが使用するコアランタイムPM API */

#include <linux/pm_runtime.h>

/* デバイスのランタイムPMを有効化 */
pm_runtime_enable(dev);

/* ランタイムPMを無効化 */
pm_runtime_disable(dev);

/* 使用カウントをインクリメントし、サスペンド中なら復帰 */
pm_runtime_get(dev);              /* 非同期 */
pm_runtime_get_sync(dev);         /* 同期 */
pm_runtime_get_noresume(dev);     /* カウントのみインクリメント */

/* 使用カウントをデクリメントし、0になったらサスペンド */
pm_runtime_put(dev);              /* 非同期 */
pm_runtime_put_sync(dev);         /* 同期 */
pm_runtime_put_autosuspend(dev);  /* 自動サスペンド遅延付き */

/* 自動サスペンド遅延の設定 */
pm_runtime_set_autosuspend_delay(dev, 2000);  /* 2秒 */
pm_runtime_use_autosuspend(dev);

/* デバイスをアクティブ/サスペンドとしてマーク */
pm_runtime_set_active(dev);
pm_runtime_set_suspended(dev);

6.4 ランタイムPM実装例

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>

struct my_device {
    void __iomem *regs;
    struct clk *clk;
    struct device *dev;
};

static int my_runtime_suspend(struct device *dev)
{
    struct my_device *mydev = dev_get_drvdata(dev);

    /* 揮発性レジスタを保存 */
    /* 省電力のためクロックを無効化 */
    clk_disable_unprepare(mydev->clk);

    dev_dbg(dev, "ランタイムサスペンド完了\n");
    return 0;
}

static int my_runtime_resume(struct device *dev)
{
    struct my_device *mydev = dev_get_drvdata(dev);
    int ret;

    /* クロックを再有効化 */
    ret = clk_prepare_enable(mydev->clk);
    if (ret) {
        dev_err(dev, "クロック有効化失敗: %d\n", ret);
        return ret;
    }

    dev_dbg(dev, "ランタイムレジューム完了\n");
    return 0;
}

/* デバイスがアクティブである必要があるI/O操作 */
static ssize_t my_device_read(struct file *file, char __user *buf,
                               size_t count, loff_t *ppos)
{
    struct my_device *mydev = file->private_data;
    int ret;
    u32 data;

    /* デバイスが電源オンであることを保証 */
    ret = pm_runtime_get_sync(mydev->dev);
    if (ret < 0) {
        pm_runtime_put_noidle(mydev->dev);
        return ret;
    }

    /* 実際のI/Oを実行 */
    data = readl(mydev->regs + DATA_OFFSET);

    /* 自動サスペンド遅延後にデバイスのサスペンドを許可 */
    pm_runtime_mark_last_busy(mydev->dev);
    pm_runtime_put_autosuspend(mydev->dev);

    return simple_read_from_buffer(buf, count, ppos, &data, sizeof(data));
}

static int my_device_probe(struct platform_device *pdev)
{
    struct my_device *mydev;

    mydev = devm_kzalloc(&pdev->dev, sizeof(*mydev), GFP_KERNEL);
    if (!mydev)
        return -ENOMEM;

    mydev->dev = &pdev->dev;
    platform_set_drvdata(pdev, mydev);

    /* ランタイムPMの設定 */
    pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);  /* 2秒遅延 */
    pm_runtime_use_autosuspend(&pdev->dev);
    pm_runtime_set_active(&pdev->dev);
    pm_runtime_enable(&pdev->dev);

    return 0;
}

6.5 ユーザー空間からのランタイムPM

# デバイスのランタイムPM状態を確認
cat /sys/devices/pci0000:00/0000:00:1f.3/power/runtime_status
# active, suspended, suspending, resuming, error

# ランタイムPMの有効化/無効化
echo auto | sudo tee /sys/devices/pci0000:00/0000:00:1f.3/power/control
echo on | sudo tee /sys/devices/pci0000:00/0000:00:1f.3/power/control

# 自動サスペンド遅延の設定 (ミリ秒)
echo 5000 | sudo tee /sys/devices/pci0000:00/0000:00:1f.3/power/autosuspend_delay_ms

# 全PCIデバイスのランタイムPMを有効化
for dev in /sys/bus/pci/devices/*/power/control; do
    echo auto > "$dev"
done

7. CPU周波数スケーリング (cpufreqサブシステム)

7.1 概要

cpufreqサブシステムは、Linuxカーネルがパフォーマンスと消費電力のバランスを取るために、CPUの動作周波数と電圧を動的に調整する機能 (DVFS - Dynamic Voltage and Frequency Scaling) を提供します。

7.2 アーキテクチャ

+----------------------------------------------------------+
|                    ユーザー空間                              |
|  cpupower, /sys/devices/system/cpu/cpufreq/              |
+----------------------------------------------------------+
|                    cpufreqコア                              |
|  (drivers/cpufreq/cpufreq.c)                             |
|  +------------------+  +-----------------------------+   |
|  | 周波数ガバナー     |  | ポリシー管理                  |   |
|  |                   |  | (CPU単位/共有ポリシー)         |   |
|  +------------------+  +-----------------------------+   |
+----------------------------------------------------------+
|                スケーリングドライバ                           |
|  +--------------+  +---------------+  +---------------+  |
|  | intel_pstate |  | amd-pstate    |  | acpi-cpufreq  |  |
|  +--------------+  +---------------+  +---------------+  |
+----------------------------------------------------------+
|                    ハードウェア                              |
|  (CPU P-states, ACPI _PSS/_PCT, CPPCレジスタ)            |
+----------------------------------------------------------+

7.3 sysfsインターフェース

# CPU周波数情報
ls /sys/devices/system/cpu/cpu0/cpufreq/

# 主要ファイル:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
# intel_pstate / acpi-cpufreq / amd-pstate 等

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# performance / powersave / ondemand / conservative / schedutil

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
# performance powersave

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# 800000 1000000 1200000 ... 3600000 (KHz単位)

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
# 2400000 (現在の周波数、KHz)

cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq
# 800000 (ハードウェア最低周波数)

cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
# 5000000 (ハードウェア最高周波数)

# グローバルcpufreqブースト制御
cat /sys/devices/system/cpu/cpufreq/boost
# 1 (ターボ/ブースト有効)
echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost  # ターボ無効化

# 周波数遷移統計
cat /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
# freq      time (10ms単位)
# 800000    523461
# 1000000   84532
# 5000000   12453

cat /sys/devices/system/cpu/cpu0/cpufreq/stats/total_trans
# 154823 (周波数遷移の総回数)

7.4 CPU周波数の設定

# 全CPUにガバナーを設定
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
    echo "performance" | sudo tee "$cpu"
done

# 最低周波数 (フロア) の設定
echo 2000000 | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq

# 最高周波数 (シーリング) の設定
echo 3500000 | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq

# cpupowerツールの使用
sudo cpupower frequency-set -g performance     # ガバナー設定
sudo cpupower frequency-set -d 800MHz          # 最低周波数設定
sudo cpupower frequency-set -u 3.5GHz          # 最高周波数設定
sudo cpupower frequency-set -f 2.4GHz          # 固定周波数設定

# 特定CPUへの設定
sudo cpupower -c 0-3 frequency-set -g powersave
sudo cpupower -c 4-7 frequency-set -g performance

# リアルタイム周波数変化の監視
watch -n 0.5 "cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq"

8. CPU周波数ガバナー

8.1 概要

CPU周波数ガバナーは、現在の負荷とポリシーに基づいてCPUがどの周波数/電圧で動作するかを決定するアルゴリズムです。

8.2 performanceガバナー

performanceガバナーは、CPUを常に許可された最大周波数に維持します。

# performanceガバナーの設定
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# ユースケース:
# - レイテンシ重視のワークロード (リアルタイム、ゲーミング、HPC)
# - ベンチマーク
# - 電力が問題にならないサーバー

8.3 powersaveガバナー

powersaveガバナーは、CPUを許可された最低周波数に維持します。

# powersaveガバナーの設定
echo powersave | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 注意: intel_pstateでは、"powersave"は異なる動作をします
# - 負荷に基づいて周波数がスケーリングされますが、低い周波数を好みます
# - acpi-cpufreqのpowersaveのような固定最低周波数ガバナーではありません

8.4 ondemandガバナー

ondemandガバナーは、CPU使用率に基づいて動的に周波数を調整します:

# ondemandガバナーの設定
echo ondemand | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 調整可能パラメータ
# 最大周波数にジャンプするしきい値 (デフォルト: 95%)
echo 80 | sudo tee /sys/devices/system/cpu/cpufreq/ondemand/up_threshold

# サンプリングレート (マイクロ秒、負荷チェック頻度)
echo 50000 | sudo tee /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate

# 周波数減少時のサンプルレートファクター
echo 1 | sudo tee /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor

# I/Oビジー検出: I/O待ちを負荷として扱う
echo 1 | sudo tee /sys/devices/system/cpu/cpufreq/ondemand/io_is_busy

# 省電力バイアス (0 = 最大パフォーマンス, 1000 = 最大省電力)
echo 200 | sudo tee /sys/devices/system/cpu/cpufreq/ondemand/powersave_bias

8.5 conservativeガバナー

conservativeガバナーはondemandに似ていますが、周波数を段階的に増減します:

# conservativeガバナーの設定
echo conservative | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 調整可能パラメータ
# 周波数増加しきい値
echo 80 | sudo tee /sys/devices/system/cpu/cpufreq/conservative/up_threshold

# 周波数減少しきい値
echo 20 | sudo tee /sys/devices/system/cpu/cpufreq/conservative/down_threshold

# 周波数ステップサイズ (サンプルごとに変更する最大周波数の%)
echo 5 | sudo tee /sys/devices/system/cpu/cpufreq/conservative/freq_step

# サンプリングレート
echo 100000 | sudo tee /sys/devices/system/cpu/cpufreq/conservative/sampling_rate

8.6 schedutilガバナー

schedutilガバナーは、スケジューラのCPU使用率情報を周波数決定に使用します。最新システムに推奨されるガバナーです:

# schedutilガバナーの設定
echo schedutil | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

# 調整可能パラメータ
# 周波数変更のレート制限 (マイクロ秒)
echo 1000 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/schedutil/rate_limit_us

# schedutilガバナーの動作原理:
# 1. スケジューラがPELT (Per-Entity Load Tracking) でCPU使用率を追跡
# 2. schedutilがスケジューラにフックして使用率更新を取得
# 3. 希望周波数を計算:
#    next_freq = 1.25 * max_freq * util / max_util
#    (1.25倍のファクターでパフォーマンスのヘッドルームを提供)
# 4. rate_limit_us間隔で周波数が更新される

# ondemandに対する利点:
# - スケジューラデータを直接使用 (サンプリング不要)
# - EAS (Energy-Aware Scheduling) との統合が良好
# - 周波数変更のレイテンシが低い
# - 非対称CPUトポロジ (big.LITTLE) の処理が向上

8.7 ガバナー比較

+---------------+------------+----------+----------+-------------+
| ガバナー       | レイテンシ   | 消費電力  | オーバーヘッド| 最適用途     |
+---------------+------------+----------+----------+-------------+
| performance   | 最低        | 最高     | なし      | HPC/リアルタイム|
| powersave     | 最高        | 最低     | なし      | アイドル/バッテリー|
| ondemand      | 低-中       | 中       | 定期的    | 汎用         |
| conservative  | 中          | 中-低    | 定期的    | 組み込み      |
| schedutil     | 低          | 中-低    | 最小限    | 最新システム   |
+---------------+------------+----------+----------+-------------+

9. CPUアイドル状態 (cpuidle)

9.1 概要

CPUコアに処理するべき仕事がない場合、消費電力を節約するために段階的に深いアイドル状態 (C-states) に入ることができます。深い状態ほどより多くの電力を節約しますが、復帰にかかる時間も長くなります。

9.2 C-State定義

C-State名称説明復帰レイテンシ消費電力
C0ActiveCPU命令実行中0最大
C1HaltCPUクロック停止 (HLT命令)約1 usC0の約85%
C1EEnhanced HaltC1 + 電圧低減約2 usC0の約75%
C3SleepL1/L2キャッシュフラッシュ、クロック停止約50 usC0の約30%
C6Deep Power Downコア電圧をほぼ0に低減約100 usC0の約10%
C7Package C7L3キャッシュフラッシュ約150 usC0の約5%
C8Package C8PLL無効化約200 usC0の約3%
C10Package C10ほぼ電源オフ約500 usC0の約1%

9.3 cpuidleフレームワーク

+-----------------------------------------------+
|              cpuidleフレームワーク                |
|  (drivers/cpuidle/cpuidle.c)                   |
+-----------------------------------------------+
|                                                 |
|  +-------------------+  +--------------------+ |
|  | cpuidleガバナー    |  | cpuidleドライバ     | |
|  | (アイドル状態選択)  |  | (HW操作)           | |
|  +-------------------+  +--------------------+ |
|  | menuガバナー       |  | intel_idle         | |
|  | teoガバナー        |  | acpi_idle          | |
|  | ladderガバナー     |  | arm_idle           | |
|  | haltpollガバナー   |  | psci_idle          | |
|  +-------------------+  +--------------------+ |
+-----------------------------------------------+

9.4 cpuidleのsysfsインターフェース

# cpuidleドライバとガバナー
cat /sys/devices/system/cpu/cpuidle/current_driver
# intel_idle

cat /sys/devices/system/cpu/cpuidle/current_governor
# menu

# CPU単位のアイドル状態情報
# 各状態 (state0, state1, state2等) に対して:
cat /sys/devices/system/cpu/cpu0/cpuidle/state0/name
# POLL
cat /sys/devices/system/cpu/cpu0/cpuidle/state0/latency
# 0 (マイクロ秒)
cat /sys/devices/system/cpu/cpu0/cpuidle/state0/residency
# 0 (省電力のための最小滞在時間、マイクロ秒)
cat /sys/devices/system/cpu/cpu0/cpuidle/state0/time
# 9385238 (この状態の合計時間、マイクロ秒)
cat /sys/devices/system/cpu/cpu0/cpuidle/state0/usage
# 43526 (この状態に入った回数)
cat /sys/devices/system/cpu/cpu0/cpuidle/state0/disable
# 0 (0=有効, 1=無効)

# 例: CPU 0の全C-stateを一覧
for state in /sys/devices/system/cpu/cpu0/cpuidle/state*/; do
    name=$(cat "$state/name")
    latency=$(cat "$state/latency")
    residency=$(cat "$state/residency")
    usage=$(cat "$state/usage")
    time=$(cat "$state/time")
    disable=$(cat "$state/disable")
    printf "%-10s レイテンシ=%5d us  残留=%6d us  使用回数=%8d  時間=%12d us  無効=%s\n" \
        "$name" "$latency" "$residency" "$usage" "$time" "$disable"
done

9.5 C-Stateの制御

# 特定のC-stateを無効化
echo 1 | sudo tee /sys/devices/system/cpu/cpu0/cpuidle/state3/disable

# 全CPUの深いC-stateを無効化 (レイテンシ重視のワークロード向け)
for cpu in /sys/devices/system/cpu/cpu*/cpuidle/; do
    for state in "$cpu"state*/; do
        latency=$(cat "$state/latency")
        if [ "$latency" -gt 100 ]; then
            echo 1 > "$state/disable"
        fi
    done
done

# C-stateを制限するカーネルパラメータ
# processor.max_cstate=1  -- C1のみに制限
# intel_idle.max_cstate=3 -- intel_idleをC3に制限

# PM QoS: ユーザー空間からCPUレイテンシ要件を設定
# /dev/cpu_dma_latency: 32ビット値を書き込み (マイクロ秒)
# fdが開いている間、カーネルはこのレイテンシを超える深いC-stateに入らない
# 0 = C0以外のアイドル状態なし

# 例: 深いアイドル状態を防止
exec 3<> /dev/cpu_dma_latency
echo -ne '\x00\x00\x00\x00' >&3  # 0マイクロ秒 - C0を強制
# ... レイテンシ重視のワークロードを実行 ...
exec 3>&-  # ファイルディスクリプタを閉じて制約を解除

9.6 cpuidleガバナー

Menuガバナー

パターンベースのアプローチでアイドル時間を予測するデフォルトのガバナー:

# menuガバナーの設定
echo menu | sudo tee /sys/devices/system/cpu/cpuidle/current_governor

# menuガバナーが考慮する要素:
# - 予想アイドル時間 (次のタイマーイベントに基づく)
# - 過去のアイドルパターン (補正係数)
# - レイテンシ要件 (PM QoS)
# - パフォーマンス乗数 (対話的ワークロード用)

TEOガバナー (Timer Events Oriented)

# TEOガバナーの設定 (カーネル5.1以降)
echo teo | sudo tee /sys/devices/system/cpu/cpuidle/current_governor

# TEOの設計目標:
# - タイマーイベントに基づくアイドル時間のより良い予測
# - ウェイクアップレイテンシのジッター削減
# - 不必要に深いアイドル状態の回避
# - ティックレス (NO_HZ) 設定との良好な連携

10. Intel P-StatesとAMD P-Statesドライバ

10.1 Intel P-States (intel_pstate)

intel_pstateドライバは、より効率的な周波数管理のために従来のcpufreqガバナーフレームワークをバイパスする、Intel最新のCPU周波数スケーリングドライバです。

動作モード

# 現在のモードを確認
cat /sys/devices/system/cpu/intel_pstate/status
# active    -- intel_pstateが直接周波数を管理 (利用可能ならHWP)
# passive   -- intel_pstateがcpufreqドライバとしてガバナーと連携
# off       -- intel_pstateは無効

# モード切替
echo passive | sudo tee /sys/devices/system/cpu/intel_pstate/status
echo active | sudo tee /sys/devices/system/cpu/intel_pstate/status

# intel_pstateを完全に無効化 (ブートパラメータ)
# intel_pstate=disable    -> acpi-cpufreqにフォールバック
# intel_pstate=passive    -> ブート時にpassiveモード
# intel_pstate=no_hwp     -> Hardware P-state (HWP) 制御を無効化

アクティブモード (HWP)

# Hardware P-states (HWP) では、CPUハードウェアが周波数を管理
# ドライバはヒントと制約を設定

# HWPがアクティブか確認
cat /sys/devices/system/cpu/intel_pstate/hwp_dynamic_boost

# intel_pstateアクティブモードのsysfsパラメータ
cat /sys/devices/system/cpu/intel_pstate/max_perf_pct    # 最大パフォーマンス%
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct    # 最小パフォーマンス%
cat /sys/devices/system/cpu/intel_pstate/no_turbo         # 1 = ターボ無効
cat /sys/devices/system/cpu/intel_pstate/turbo_pct        # ターボ範囲の%
cat /sys/devices/system/cpu/intel_pstate/num_pstates      # P-stateの数

# パフォーマンス制限の調整
echo 50 | sudo tee /sys/devices/system/cpu/intel_pstate/min_perf_pct
echo 100 | sudo tee /sys/devices/system/cpu/intel_pstate/max_perf_pct

# ターボブーストの無効化
echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

# CPU単位のEnergy Performance Preference (EPP)
cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference
# default, performance, balance_performance, balance_power, power

echo balance_performance | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference

10.2 AMD P-States (amd-pstate)

amd-pstateドライバは、CPPC (Collaborative Processor Performance Control) をサポートする最新のAMDプロセッサをサポートします:

# amd-pstateの状態確認
cat /sys/devices/system/cpu/amd_pstate/status
# active, passive, guided, または disable

# amd-pstateの有効化 (ブートパラメータ)
# amd_pstate=active     -- EPPモード (AMD推奨)
# amd_pstate=passive    -- cpufreqガバナーと連携
# amd_pstate=guided     -- OSが要求、プラットフォームが決定

# ランタイムでのモード切替
echo active | sudo tee /sys/devices/system/cpu/amd_pstate/status
echo guided | sudo tee /sys/devices/system/cpu/amd_pstate/status

# AMD固有の周波数情報
cat /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_highest_perf
cat /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_lowest_nonlinear_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_max_freq

# 優先コアランキング (Ryzen 7000+)
cat /sys/devices/system/cpu/cpu0/cpufreq/amd_pstate_prefcore_ranking

10.3 比較: intel_pstate vs amd-pstate vs acpi-cpufreq

+------------------+----------------+----------------+----------------+
| 機能              | intel_pstate   | amd-pstate     | acpi-cpufreq   |
+------------------+----------------+----------------+----------------+
| ハードウェア制御   | HWP (active)   | CPPC (active)  | ACPI _PSS/_PCT |
| ガバナー          | 独自/cpufreq   | 独自/cpufreq   | cpufreqのみ    |
| 粒度              | 細かい (1 MHz) | 細かい (1 MHz) | 離散ステップ    |
| ターボ制御        | コア単位       | コア単位        | グローバルのみ  |
| EPPサポート       | あり           | あり           | なし            |
| 優先コア          | あり (12世代+) | あり (Ryzen 7k)| なし            |
+------------------+----------------+----------------+----------------+

11. エネルギー考慮スケジューリング (EAS)

11.1 概要

Energy-Aware Scheduling (EAS) は、LinuxスケジューラがCPUにタスクを配置する際にエネルギー消費を考慮するCFS (Completely Fair Scheduler) の機能です。特にヘテロジニアスCPUアーキテクチャ (ARM big.LITTLE、IntelハイブリッドアーキテクチャのP-coreとE-core等) で重要です。

11.2 EASの動作原理

+------------------------------------------+
|          CFSスケジューラ                    |
|  +------------------------------------+  |
|  | タスクウェイクアップ / マイグレーション |  |
|  |   1. 候補CPUを見つける               |  |
|  |   2. 各候補について:                 |  |
|  |      - 配置した場合のエネルギーを推定  |  |
|  |      - エネルギーモデルデータを使用    |  |
|  |   3. 最低エネルギーのCPUを選択        |  |
|  +------------------------------------+  |
+------------------------------------------+
|          エネルギーモデル                   |
|  +------------------------------------+  |
|  | CPU単位のパフォーマンスドメイン        |  |
|  | +------+  +------+  +------+       |  |
|  | |Little|  |Medium|  | Big  |       |  |
|  | |CPU0-3|  |CPU4-5|  |CPU6-7|       |  |
|  | +------+  +------+  +------+       |  |
|  |                                     |  |
|  | OPPテーブル (各ドメイン):             |  |
|  | 周波数 (KHz)  | 電圧    | 電力 (mW) |  |
|  | 500000        | 0.65V  | 100       |  |
|  | 1000000       | 0.80V  | 300       |  |
|  | 1500000       | 0.95V  | 700       |  |
|  | 2000000       | 1.10V  | 1200      |  |
|  +------------------------------------+  |
+------------------------------------------+

11.3 EASの前提条件

# EASの要件:
# 1. CPUのエネルギーモデルが登録されていること
# 2. schedutilガバナーがアクティブ
# 3. スケール不変CPU周波数 (arch_scale_freq_capacity)
# 4. CONFIG_ENERGY_MODEL=y

# EASがアクティブか確認
cat /sys/kernel/debug/sched/energy_aware
# 1 = 有効

# Intelハイブリッド (第12世代+)
# EASはタスクをE-coreとP-coreに効率的に配置するのに役立つ
cat /sys/devices/system/cpu/cpu0/cpu_capacity
# P-coreは通常1024 (最大容量)
# E-coreは通常低い値 (例: 512)

# CPU単位の容量
for cpu in /sys/devices/system/cpu/cpu*/cpu_capacity; do
    echo "$(dirname $cpu | xargs basename): $(cat $cpu)"
done

11.4 省電力のためのスケジューラチューニング

# 消費電力に影響するスケジューラパラメータ

# マイグレーションコスト (高い=マイグレーション減=キャッシュ良好だがエネルギー非効率の可能性)
cat /proc/sys/kernel/sched_migration_cost_ns
# デフォルト: 500000 (500 us)

# 電力制限シナリオのCFS帯域幅制御
# CPU帯域幅制限付きcgroupの作成
mkdir -p /sys/fs/cgroup/cpu/power_limited
echo 50000 > /sys/fs/cgroup/cpu/power_limited/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/power_limited/cpu.cfs_period_us
# このグループのタスクをCPU時間の50%に制限

# cgroup v2でのより精密な制御
echo "50000 100000" > /sys/fs/cgroup/power_limited/cpu.max

12. サーマル管理

12.1 概要

Linuxのサーマルフレームワークは、サーマルゾーンを監視し、温度が定義されたしきい値 (トリップポイント) を超えた場合に冷却アクションを適用することで、システム温度を管理します。

12.2 サーマルフレームワークアーキテクチャ

+----------------------------------------------------------+
|                   ユーザー空間                              |
|  (thermald, /sys/class/thermal/)                         |
+----------------------------------------------------------+
|                サーマルフレームワーク                        |
|  (drivers/thermal/thermal_core.c)                        |
|  +--------------------------------------------------+   |
|  |              サーマルガバナー                        |   |
|  | step_wise | bang_bang | power_allocator | user_space| |
|  +--------------------------------------------------+   |
|  +---------------------+  +-------------------------+   |
|  | サーマルゾーン        |  | 冷却デバイス              |  |
|  | (温度センサー)        |  | (ファン、周波数制限器)     |  |
|  +---------------------+  +-------------------------+   |
+----------------------------------------------------------+
|                ハードウェアセンサーとアクチュエータ           |
|  (CPUサーマル、PCH、GPU、SSD、ファンコントローラ)          |
+----------------------------------------------------------+

12.3 サーマルゾーン

# 全サーマルゾーンの一覧
ls /sys/class/thermal/thermal_zone*/

# 各サーマルゾーンの情報:
cat /sys/class/thermal/thermal_zone0/type
# x86_pkg_temp / acpitz / pch_skylake / iwlwifi_1

cat /sys/class/thermal/thermal_zone0/temp
# 45000 (ミリ度摂氏 = 45.0度C)

cat /sys/class/thermal/thermal_zone0/policy
# step_wise (現在のガバナー)

# トリップポイント
cat /sys/class/thermal/thermal_zone0/trip_point_0_temp
# 87000 (87度C)
cat /sys/class/thermal/thermal_zone0/trip_point_0_type
# passive / active / hot / critical

# 例: 全サーマルゾーンの温度を表示
for zone in /sys/class/thermal/thermal_zone*/; do
    type=$(cat "$zone/type")
    temp=$(cat "$zone/temp" 2>/dev/null)
    if [ -n "$temp" ]; then
        temp_c=$(echo "scale=1; $temp/1000" | bc)
        printf "%-20s %s 度C\n" "$type" "$temp_c"
    fi
done

# リアルタイム温度監視
watch -n 1 'for z in /sys/class/thermal/thermal_zone*/; do
    echo "$(cat $z/type): $(cat $z/temp 2>/dev/null)m度C"
done'

12.4 トリップポイント

# トリップポイントの種類:
# - passive: 温度を制限するためにパフォーマンスを低下 (CPUスロットリング)
# - active: 冷却デバイスを有効化 (ファンをオン)
# - hot: システム固有のアクション (積極的なスロットリング)
# - critical: ハードウェア保護のための緊急シャットダウン

# ゾーン0の全トリップポイントを一覧
for i in $(seq 0 10); do
    type_file="/sys/class/thermal/thermal_zone0/trip_point_${i}_type"
    temp_file="/sys/class/thermal/thermal_zone0/trip_point_${i}_temp"
    if [ -f "$type_file" ]; then
        type=$(cat "$type_file")
        temp=$(cat "$temp_file")
        echo "トリップ $i: $type @ ${temp}m度C ($(echo "scale=1; $temp/1000" | bc)度C)"
    fi
done

12.5 冷却デバイス

# 冷却デバイスの一覧
ls /sys/class/thermal/cooling_device*/

# 各冷却デバイスの情報:
cat /sys/class/thermal/cooling_device0/type
# Processor / Fan / intel_powerclamp / thermal-devfreq

cat /sys/class/thermal/cooling_device0/max_state
# 10 (最大冷却努力)

cat /sys/class/thermal/cooling_device0/cur_state
# 0 (現在の冷却努力, 0 = 冷却なし)

# 冷却デバイス状態の手動設定
echo 5 | sudo tee /sys/class/thermal/cooling_device0/cur_state

# 例: 全冷却デバイスの状態を一覧
for dev in /sys/class/thermal/cooling_device*/; do
    type=$(cat "$dev/type")
    cur=$(cat "$dev/cur_state")
    max=$(cat "$dev/max_state")
    printf "%-30s 状態: %s/%s\n" "$type" "$cur" "$max"
done

12.6 サーマルガバナー

# Step-wiseガバナー: 冷却状態を段階的に調整
echo step_wise | sudo tee /sys/class/thermal/thermal_zone0/policy

# Bang-bangガバナー: オン/オフ制御 (ファンに適している)
echo bang_bang | sudo tee /sys/class/thermal/thermal_zone0/policy

# Power Allocatorガバナー: IPA (Intelligent Power Allocation)
# PIDコントローラによる精密なサーマル管理
echo power_allocator | sudo tee /sys/class/thermal/thermal_zone0/policy

# Power Allocatorパラメータ (サーマルゾーン単位)
cat /sys/class/thermal/thermal_zone0/sustainable_power
# ミリワット単位の電力バジェット
echo 5000 | sudo tee /sys/class/thermal/thermal_zone0/sustainable_power

12.7 Intel thermald

# Intelサーマルデーモンによる高度なサーマル管理
sudo apt install thermald

# 起動と有効化
sudo systemctl enable --now thermald

# カスタムサーマル設定例
cat > /etc/thermald/thermal-conf.xml << 'EOF'
<?xml version="1.0"?>
<ThermalConfiguration>
  <Platform>
    <Name>カスタムサーマルポリシー</Name>
    <ProductName>*</ProductName>
    <ThermalZones>
      <ThermalZone>
        <Type>x86_pkg_temp</Type>
        <TripPoints>
          <TripPoint>
            <SensorType>x86_pkg_temp</SensorType>
            <Temperature>80000</Temperature>
            <Type>passive</Type>
            <CoolingDevice>
              <Type>Processor</Type>
              <influence>100</influence>
              <SamplingPeriod>5</SamplingPeriod>
            </CoolingDevice>
          </TripPoint>
          <TripPoint>
            <SensorType>x86_pkg_temp</SensorType>
            <Temperature>95000</Temperature>
            <Type>passive</Type>
            <CoolingDevice>
              <Type>intel_powerclamp</Type>
              <influence>50</influence>
            </CoolingDevice>
          </TripPoint>
        </TripPoints>
      </ThermalZone>
    </ThermalZones>
  </Platform>
</ThermalConfiguration>
EOF

sudo systemctl restart thermald

13. デバイス電力管理

13.1 struct dev_pm_ops

dev_pm_ops構造体は、Linuxカーネルにおけるデバイス電力管理の中心的なインターフェースです。様々な電力管理遷移のためのコールバックを定義します。

/* include/linux/pm.h から */
struct dev_pm_ops {
    /* システムスリープ (サスペンド/ハイバネーション) */
    int (*prepare)(struct device *dev);
    void (*complete)(struct device *dev);
    int (*suspend)(struct device *dev);
    int (*resume)(struct device *dev);
    int (*freeze)(struct device *dev);        /* ハイバネーション: スナップショット作成 */
    int (*thaw)(struct device *dev);          /* ハイバネーション: キャンセル */
    int (*poweroff)(struct device *dev);      /* ハイバネーション: スナップショット後 */
    int (*restore)(struct device *dev);       /* ハイバネーション: 復元後 */

    /* Late/Earlyバリアント */
    int (*suspend_late)(struct device *dev);
    int (*resume_early)(struct device *dev);

    /* No-IRQバリアント (割り込み無効状態で呼び出し) */
    int (*suspend_noirq)(struct device *dev);
    int (*resume_noirq)(struct device *dev);

    /* ランタイムPM */
    int (*runtime_suspend)(struct device *dev);
    int (*runtime_resume)(struct device *dev);
    int (*runtime_idle)(struct device *dev);
};

13.2 コールバックフロー図

システムサスペンド:
  prepare() -> suspend() -> suspend_late() -> suspend_noirq()

システムレジューム:
  resume_noirq() -> resume_early() -> resume() -> complete()

ハイバネーション (フリーズパス):
  prepare() -> freeze() -> freeze_late() -> freeze_noirq()
  [スナップショット作成]
  thaw_noirq() -> thaw_early() -> thaw() -> complete()

ハイバネーション (電源オフパス - スナップショット後):
  prepare() -> poweroff() -> poweroff_late() -> poweroff_noirq()
  [システム電源オフ]

ハイバネーション (復元パス - ブート後):
  [スナップショット復元]
  restore_noirq() -> restore_early() -> restore() -> complete()

13.3 ヘルパーマクロ

/* dev_pm_opsの定義に使用される一般的なパターン */

/* サスペンド/フリーズ/パワーオフとレジューム/解凍/復元に同じ関数を使用 */
static SIMPLE_DEV_PM_OPS(my_pm_ops, my_suspend, my_resume);

/* 最新マクロ (カーネル5.17+) */
static const struct dev_pm_ops my_pm_ops = {
    SYSTEM_SLEEP_PM_OPS(my_suspend, my_resume)
    RUNTIME_PM_OPS(my_runtime_suspend, my_runtime_resume, my_runtime_idle)
};

/* pm_sleep_ptr()を使用してPMサポートを条件付きコンパイル */
static struct platform_driver my_driver = {
    .driver = {
        .name = "my-device",
        .pm = pm_sleep_ptr(&my_pm_ops),
    },
};

13.4 ウェイクアップソース

# ユーザー空間からウェイクアップソースを表示
cat /sys/kernel/debug/wakeup_sources
# name            active_count  event_count  wakeup_count  expire_count  ...
# Power Button           0            0            0             0
# Lid Switch             1            3            1             0

# デバイス単位のウェイクアップ制御
echo enabled | sudo tee /sys/devices/.../power/wakeup
echo disabled | sudo tee /sys/devices/.../power/wakeup

# システムを起こしたデバイスを確認
dmesg | grep -i "wakeup source"

14. PCI電力管理

14.1 PCI電力状態

PCIは4つのデバイス電力状態を定義しています:

状態名称説明消費電力状態保持
D0Fully Onデバイス完全稼働最大全て
D1Light Sleepベンダー固有の低電力減少ほぼ全て
D2Deeper Sleepベンダー固有のさらに低い電力より低い少ない
D3hotSoft OffVcc付きの最低電力最小PMEのみ
D3coldHard OffVcc完全除去なしなし

14.2 LinuxにおけるPCI PM

# PCIデバイスの電力状態を確認
lspci -vv -s 00:1f.3 | grep -i "power\|status"
# Capabilities: [60] Power Management version 3
#     Status: D0 PME-Enable- DSel=0 DScale=0 PME-

# sysfs経由での電力状態確認
cat /sys/bus/pci/devices/0000:00:1f.3/power_state
# D0

# 全PCIデバイスの電力状態を一覧
for dev in /sys/bus/pci/devices/*/; do
    addr=$(basename "$dev")
    state=$(cat "$dev/power_state" 2>/dev/null)
    driver=$(readlink "$dev/driver" 2>/dev/null | xargs basename 2>/dev/null)
    echo "$addr  状態=$state  ドライバ=$driver"
done

14.3 PCI ランタイムPM

# PCIデバイスのランタイムPMを有効化
echo auto | sudo tee /sys/bus/pci/devices/0000:00:1f.3/power/control

# 自動サスペンド遅延の設定
echo 5000 | sudo tee /sys/bus/pci/devices/0000:00:1f.3/power/autosuspend_delay_ms

# ASPM (Active State Power Management) の確認
lspci -vv | grep -i aspm
# LnkCtl: ASPM L1 Enabled
# L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+

# ASPMポリシー
cat /sys/module/pcie_aspm/parameters/policy
# [default] performance powersave powersupersave

# ASPMポリシーの設定
echo powersave | sudo tee /sys/module/pcie_aspm/parameters/policy

# ASPM用カーネルパラメータ
# pcie_aspm=force       -- BIOSが無効にしてもASPMを強制
# pcie_aspm=off         -- ASPMを無効化
# pcie_aspm.policy=powersave  -- デフォルトをpowersaveに

14.4 PCI PMドライバ実装

#include <linux/pci.h>
#include <linux/pm.h>

static int my_pci_suspend(struct device *dev)
{
    struct pci_dev *pdev = to_pci_dev(dev);
    struct my_pci_data *data = pci_get_drvdata(pdev);

    /* デバイス固有の状態を保存 */
    my_device_save_state(data);
    my_device_disable_irq(data);

    /* PCI標準の保存と電源ダウン */
    pci_save_state(pdev);
    pci_disable_device(pdev);
    pci_set_power_state(pdev, PCI_D3hot);

    return 0;
}

static int my_pci_resume(struct device *dev)
{
    struct pci_dev *pdev = to_pci_dev(dev);
    int ret;

    /* PCI標準の復元 */
    pci_set_power_state(pdev, PCI_D0);
    pci_restore_state(pdev);
    ret = pci_enable_device(pdev);
    if (ret)
        return ret;
    pci_set_master(pdev);

    /* デバイス固有の状態を復元 */
    my_device_restore_state(data);
    my_device_enable_irq(data);

    return 0;
}

15. USB電力管理

15.1 USB電力状態

# USBオートサスペンドにより、未使用のUSBデバイスを低電力状態にできる

# USBオートサスペンド状態の確認
cat /sys/bus/usb/devices/1-1/power/control
# auto = オートサスペンド有効
# on   = 常にアクティブ (オートサスペンドしない)

cat /sys/bus/usb/devices/1-1/power/runtime_status
# active, suspended, suspending, resuming

cat /sys/bus/usb/devices/1-1/power/autosuspend
# 2 (非アクティブ後サスペンドまでの秒数)

# 全USBデバイスのオートサスペンドを有効化
for dev in /sys/bus/usb/devices/*/power/control; do
    echo auto | sudo tee "$dev"
done

# 特定デバイスのオートサスペンドを無効化 (例: USBキーボード)
echo on | sudo tee /sys/bus/usb/devices/1-1.2/power/control

# USB電力統計
cat /sys/bus/usb/devices/1-1/power/connected_duration
cat /sys/bus/usb/devices/1-1/power/active_duration

15.2 USB PM設定の例

# USB電力管理用のudevルール
cat > /etc/udev/rules.d/50-usb-power.rules << 'EOF'
# 全USBデバイスのオートサスペンドを有効化
ACTION=="add", SUBSYSTEM=="usb", ATTR{power/control}="auto"

# 例外: USBキーボードは常にアクティブ
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c31c", \
    ATTR{power/control}="on"

# USBストレージ: より長いオートサスペンド遅延
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb-storage", \
    ATTR{power/autosuspend}="15"

# USBネットワークアダプタのオートサスペンドを無効化
ACTION=="add", SUBSYSTEM=="usb", ATTR{bInterfaceClass}=="02", \
    ATTR{power/control}="on"
EOF

# udevルールの再読み込み
sudo udevadm control --reload-rules
sudo udevadm trigger

16. パワーキャッピング (Intel RAPL)

16.1 概要

Intel RAPL (Running Average Power Limit) は、異なる電力ドメイン (パッケージ、コア、アンコア、DRAM) の消費電力を監視し制限するメカニズムを提供します。

16.2 RAPLドメイン

+------------------------------------------+
|              パッケージ (PKG)              |
|  +------------------+  +---------------+ |
|  |   コアドメイン     |  | アンコアドメイン | |
|  |  (CPUコア)        |  | (GPU, キャッシュ)| |
|  +------------------+  +---------------+ |
|  +--------------------------------------+|
|  |          DRAMドメイン                  ||
|  |    (メモリコントローラ)                 ||
|  +--------------------------------------+|
|  +--------------------------------------+|
|  |          PSYSドメイン                  ||
|  |    (SoC/プラットフォーム全体)           ||
|  +--------------------------------------+|
+------------------------------------------+

16.3 powercapフレームワーク経由のRAPL

# RAPLはpowercapフレームワークを通じて公開
ls /sys/class/powercap/

# パッケージレベルの電力制御
cat /sys/class/powercap/intel-rapl:0/name
# package-0

cat /sys/class/powercap/intel-rapl:0/energy_uj
# 123456789 (消費エネルギー、マイクロジュール)

# 電力制限
cat /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
# 28000000 (PL1: 28W、マイクロワット)

cat /sys/class/powercap/intel-rapl:0/constraint_1_power_limit_uw
# 64000000 (PL2: 64W、マイクロワット)

# コアドメイン
cat /sys/class/powercap/intel-rapl:0:0/name
# core

# DRAMドメイン
cat /sys/class/powercap/intel-rapl:0:2/name
# dram

# 電力制限の設定 (PL1 = 15W)
echo 15000000 | sudo tee /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw

# 電力制限の有効化/無効化
echo 1 | sudo tee /sys/class/powercap/intel-rapl:0/enabled
echo 0 | sudo tee /sys/class/powercap/intel-rapl:0/enabled

16.4 RAPL電力監視スクリプト

#!/bin/bash
# リアルタイムRAPL電力監視

RAPL_PKG="/sys/class/powercap/intel-rapl:0"
RAPL_CORE="/sys/class/powercap/intel-rapl:0:0"
RAPL_DRAM="/sys/class/powercap/intel-rapl:0:2"

read_energy() {
    cat "$1/energy_uj" 2>/dev/null || echo 0
}

echo "RAPL消費電力を監視中 (Ctrl+Cで停止)"
echo "時刻       | パッケージ (W) | コア (W) | DRAM (W)"
echo "-----------|---------------|----------|----------"

prev_pkg=$(read_energy "$RAPL_PKG")
prev_core=$(read_energy "$RAPL_CORE")
prev_dram=$(read_energy "$RAPL_DRAM")
prev_time=$(date +%s%N)

while true; do
    sleep 1

    curr_pkg=$(read_energy "$RAPL_PKG")
    curr_core=$(read_energy "$RAPL_CORE")
    curr_dram=$(read_energy "$RAPL_DRAM")
    curr_time=$(date +%s%N)

    dt=$(echo "scale=6; ($curr_time - $prev_time) / 1000000000" | bc)

    pkg_watts=$(echo "scale=2; ($curr_pkg - $prev_pkg) / 1000000 / $dt" | bc)
    core_watts=$(echo "scale=2; ($curr_core - $prev_core) / 1000000 / $dt" | bc)
    dram_watts=$(echo "scale=2; ($curr_dram - $prev_dram) / 1000000 / $dt" | bc)

    printf "%-10s | %13s | %8s | %8s\n" \
        "$(date +%H:%M:%S)" "$pkg_watts" "$core_watts" "$dram_watts"

    prev_pkg=$curr_pkg
    prev_core=$curr_core
    prev_dram=$curr_dram
    prev_time=$curr_time
done

16.5 perfによるRAPL測定

# コマンドの消費電力を測定
sudo perf stat -e power/energy-pkg/,power/energy-cores/,power/energy-ram/ \
    sleep 10

# 出力例:
#  'sleep 10' のパフォーマンスカウンタ統計:
#
#       5.23 Joules  power/energy-pkg/
#       2.15 Joules  power/energy-cores/
#       1.89 Joules  power/energy-ram/

# ワークロード中の電力測定
sudo perf stat -e power/energy-pkg/,power/energy-cores/ \
    -- stress-ng --cpu 4 --timeout 30

17. バッテリーとUPS管理

17.1 power_supplyクラス

Linuxカーネルは、バッテリー、ACアダプター、UPSデバイスを管理するためのpower_supplyクラスを提供しています。

# 全電源供給デバイスの一覧
ls /sys/class/power_supply/

# バッテリー情報
cat /sys/class/power_supply/BAT0/type
# Battery

cat /sys/class/power_supply/BAT0/status
# Charging / Discharging / Not charging / Full
# (充電中 / 放電中 / 非充電中 / 満充電)

cat /sys/class/power_supply/BAT0/capacity
# 85 (パーセント)

cat /sys/class/power_supply/BAT0/energy_now
# 43210000 (残りマイクロワット時)

cat /sys/class/power_supply/BAT0/energy_full
# 51000000 (満充電時のマイクロワット時)

cat /sys/class/power_supply/BAT0/energy_full_design
# 57000000 (設計容量のマイクロワット時)

cat /sys/class/power_supply/BAT0/voltage_now
# 11450000 (マイクロボルト)

cat /sys/class/power_supply/BAT0/current_now
# 1234000 (マイクロアンペア)

cat /sys/class/power_supply/BAT0/power_now
# 14130000 (マイクロワット)

cat /sys/class/power_supply/BAT0/technology
# Li-ion / Li-poly / NiMH

cat /sys/class/power_supply/BAT0/cycle_count
# 235 (充電サイクル数)

# ACアダプター情報
cat /sys/class/power_supply/AC/online
# 1 (接続中) / 0 (未接続)

# バッテリー健全性の計算
#!/bin/bash
FULL=$(cat /sys/class/power_supply/BAT0/energy_full)
DESIGN=$(cat /sys/class/power_supply/BAT0/energy_full_design)
HEALTH=$(echo "scale=1; $FULL * 100 / $DESIGN" | bc)
echo "バッテリー健全性: ${HEALTH}%"

17.2 バッテリー保護

# バッテリー充電しきい値 (ThinkPad)
echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold
echo 40 | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold

# TLPによるバッテリー管理
# /etc/tlp.conf
START_CHARGE_THRESH_BAT0=40
STOP_CHARGE_THRESH_BAT0=80

17.3 UPS監視

# NUT (Network UPS Tools) によるUPS管理
sudo apt install nut

# UPS設定
# /etc/nut/ups.conf
[myups]
    driver = usbhid-ups
    port = auto
    desc = "サーバーUPS"

# UPS状態の確認
upsc myups@localhost
# battery.charge: 100
# battery.voltage: 13.6
# ups.status: OL   (オンライン、商用電源)
# ups.status: OB    (バッテリー駆動)
# ups.status: LB    (バッテリー残量低)

18. レギュレータフレームワーク

18.1 概要

レギュレータフレームワークは、組み込みシステムやSoCに一般的に見られる電圧および電流レギュレータ (LDO、DC-DCコンバータ) を管理します。

18.2 レギュレータAPI (ドライバ開発者向け)

#include <linux/regulator/consumer.h>

/* レギュレータの取得 */
struct regulator *reg = devm_regulator_get(dev, "vdd");

/* 有効化/無効化 */
regulator_enable(reg);
regulator_disable(reg);
regulator_is_enabled(reg);

/* 電圧制御 */
regulator_set_voltage(reg, 1800000, 1800000);  /* 1.8Vに設定 */
regulator_get_voltage(reg);

/* 電流制限 */
regulator_set_current_limit(reg, 0, 500000);  /* 最大500mA */

/* 一括操作 */
static struct regulator_bulk_data supplies[] = {
    { .supply = "vdd" },
    { .supply = "vddio" },
};
devm_regulator_bulk_get(dev, ARRAY_SIZE(supplies), supplies);
regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);

18.3 レギュレータのデバッグ

# レギュレータデバッグ情報
cat /sys/kernel/debug/regulator/regulator_summary
# regulator                  use open bypass voltage current   min    max
# -------------------------------------------------------------------------
#  vdd_cpu                     1    2      0  1100mV     0mA  800mV 1400mV
#  vdd_mem                     1    1      0  1350mV     0mA 1350mV 1350mV

# レギュレータ単位の情報
ls /sys/class/regulator/
cat /sys/class/regulator/regulator.0/name
cat /sys/class/regulator/regulator.0/state
cat /sys/class/regulator/regulator.0/microvolts

19. ラップトップとサーバーの電力管理

19.1 ラップトップ固有の電力管理

ラップトップにはバッテリー寿命、薄型筐体における熱制約、ユーザー体験に焦点を当てた独自の電力管理要件があります。

主な懸念事項

  • バッテリー寿命の最大化
  • 制約された筐体でのサーマル管理
  • 高速なサスペンド/レジューム
  • ディスプレイ電力管理
  • WiFi省電力

推奨設定

# TLPを使用したラップトップ電力最適化
sudo apt install tlp tlp-rdw
sudo systemctl enable --now tlp

# /etc/tlp.d/01-laptop.conf - ラップトップ向け主要設定
cat << 'EOF' > /etc/tlp.d/01-laptop.conf
# CPU設定
CPU_SCALING_GOVERNOR_ON_AC=performance
CPU_SCALING_GOVERNOR_ON_BAT=powersave
CPU_ENERGY_PERF_POLICY_ON_AC=balance_performance
CPU_ENERGY_PERF_POLICY_ON_BAT=power
CPU_BOOST_ON_AC=1
CPU_BOOST_ON_BAT=0
CPU_HWP_DYN_BOOST_ON_AC=1
CPU_HWP_DYN_BOOST_ON_BAT=0

# プラットフォームプロファイル
PLATFORM_PROFILE_ON_AC=performance
PLATFORM_PROFILE_ON_BAT=low-power

# ディスク設定
DISK_DEVICES="nvme0n1 sda"
DISK_APM_LEVEL_ON_AC="254 254"
DISK_APM_LEVEL_ON_BAT="128 128"

# SATA積極的リンク電力管理
SATA_LINKPWR_ON_AC="med_power_with_dipm max_performance"
SATA_LINKPWR_ON_BAT="min_power med_power_with_dipm"

# PCIランタイムPM
RUNTIME_PM_ON_AC=auto
RUNTIME_PM_ON_BAT=auto

# WiFi省電力
WIFI_PWR_ON_AC=off
WIFI_PWR_ON_BAT=on

# USBオートサスペンド
USB_AUTOSUSPEND=1
USB_EXCLUDE_PHONE=1

# バッテリー充電しきい値
START_CHARGE_THRESH_BAT0=40
STOP_CHARGE_THRESH_BAT0=80

# NMIウォッチドッグ (バッテリー時に無効化して省電力)
NMI_WATCHDOG=0

# オーディオ省電力
SOUND_POWER_SAVE_ON_AC=0
SOUND_POWER_SAVE_ON_BAT=1
SOUND_POWER_SAVE_CONTROLLER=Y

# 無線デバイス管理
DEVICES_TO_DISABLE_ON_STARTUP="bluetooth wwan"
DEVICES_TO_ENABLE_ON_AC="bluetooth"
EOF

# TLP設定の適用
sudo tlp start
tlp-stat -s  # 状態確認

ディスプレイ電力管理

# DPMS (Display Power Management Signaling)
xset dpms 300 600 900  # スタンバイ、サスペンド、オフ (秒)
xset dpms force off     # ディスプレイを即座にオフ

# バックライト制御
cat /sys/class/backlight/intel_backlight/brightness
cat /sys/class/backlight/intel_backlight/max_brightness
echo 500 | sudo tee /sys/class/backlight/intel_backlight/brightness

WiFi省電力

# WiFi電力管理の確認
iwconfig wlan0 | grep "Power Management"

# WiFi省電力の無効化 (レイテンシ改善)
sudo iwconfig wlan0 power off
sudo iw dev wlan0 set power_save off

# NetworkManager経由での永続設定
# /etc/NetworkManager/conf.d/wifi-powersave.conf
[connection]
wifi.powersave = 2  # 1=無効, 2=無効, 3=有効

# Intel WiFiモジュールパラメータ
echo "options iwlwifi power_save=0" | sudo tee /etc/modprobe.d/iwlwifi.conf
echo "options iwlmvm power_scheme=1" | sudo tee -a /etc/modprobe.d/iwlwifi.conf

19.2 サーバー固有の電力管理

サーバーはスケールでの電力効率に焦点を当てており、ラップトップとは異なる優先事項があります。

主な懸念事項

  • 総所有コスト (TCO)
  • 電力使用効率 (PUE)
  • ワットあたりのパフォーマンス最適化
  • 一貫した低レイテンシと省電力のトレードオフ
  • リモート管理 (IPMI/BMC)

サーバー電力最適化

# サーバー向けチューニング

# 1. CPUガバナー: ワークロードタイプに基づいて選択
# レイテンシ重視 (データベース、トレーディング):
sudo cpupower frequency-set -g performance

# スループット重視 (バッチ処理):
sudo cpupower frequency-set -g schedutil

# 2. レイテンシ重要なサーバーでは不要なC-stateを無効化
for cpu in /sys/devices/system/cpu/cpu*/cpuidle/; do
    for state in "$cpu"state*/; do
        name=$(cat "$state/name" 2>/dev/null)
        if [[ "$name" == "C6" ]] || [[ "$name" == "C7" ]]; then
            echo 1 > "$state/disable"
        fi
    done
done

# 3. ターボブースト管理
# バーストワークロード向けにターボを維持
echo 0 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

# 一貫した予測可能なパフォーマンスのためにターボを無効化
echo 1 | sudo tee /sys/devices/system/cpu/intel_pstate/no_turbo

# 4. NUMA考慮電力管理
numactl --hardware

# 5. データセンター電力バジェットのパワーキャッピング
# パッケージ電力制限を120Wに設定
echo 120000000 | sudo tee /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw

# 6. PCIe ASPM (サーバーではレイテンシのため通常無効)
echo performance | sudo tee /sys/module/pcie_aspm/parameters/policy

# 7. IPMI電力監視
ipmitool sdr type "Power Supply"
ipmitool dcmi power reading
ipmitool dcmi power get_limit
ipmitool dcmi power set_limit limit 500  # 500W電力上限を設定

サーバー電力監視

# 包括的サーバー電力監視スクリプト
#!/bin/bash
echo "=== サーバー電力状態 ==="
echo "日時: $(date)"
echo ""

echo "--- CPU情報 ---"
echo "ガバナー: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)"
echo "ドライバ: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver)"
echo "ターボ: $(if [ $(cat /sys/devices/system/cpu/intel_pstate/no_turbo 2>/dev/null) = 0 ]; then echo 有効; else echo 無効; fi)"
echo ""

echo "--- RAPL電力 ---"
if [ -d /sys/class/powercap/intel-rapl:0 ]; then
    for domain in /sys/class/powercap/intel-rapl:0*; do
        name=$(cat "$domain/name")
        energy=$(cat "$domain/energy_uj")
        printf "%-15s エネルギー: %d J\n" "$name" "$((energy/1000000))"
    done
fi
echo ""

echo "--- サーマル ---"
for zone in /sys/class/thermal/thermal_zone*/; do
    type=$(cat "$zone/type")
    temp=$(cat "$zone/temp" 2>/dev/null)
    if [ -n "$temp" ]; then
        printf "%-20s %d.%d 度C\n" "$type" "$((temp/1000))" "$((temp%1000/100))"
    fi
done
echo ""

echo "--- PCI ランタイムPM ---"
active=0; suspended=0
for dev in /sys/bus/pci/devices/*/power/runtime_status; do
    status=$(cat "$dev")
    case $status in
        active) ((active++)) ;;
        suspended) ((suspended++)) ;;
    esac
done
echo "PCIデバイス: $active アクティブ, $suspended サスペンド中"

19.3 比較表

+------------------------+------------------+------------------+
| 観点                    | ラップトップ       | サーバー          |
+------------------------+------------------+------------------+
| 主目標                  | バッテリー寿命    | $/ワット効率      |
| CPUガバナー             | schedutil/       | performance/     |
|                        | powersave        | schedutil        |
| C-States               | 深い状態を有効    | 浅い状態を好む    |
| ターボブースト          | 文脈依存          | ワークロード依存  |
| PCIe ASPM              | 有効              | 多くの場合無効    |
| USBオートサスペンド      | 積極的            | 最小限            |
| WiFi省電力              | 有効              | N/A               |
| ディスプレイPM          | 重要              | N/A               |
| RAPL電力制限            | TDP制限           | DCパワーキャップ  |
| サーマル管理            | 積極的            | ファン冷却        |
| サスペンド/ハイバネーション| 必須             | ほとんど未使用    |
| ランタイムPM            | 積極的            | 選択的            |
| 電力監視               | upower/TLP       | IPMI/RAPL        |
+------------------------+------------------+------------------+

20. 電力管理ツール

20.1 powertop

PowerTOPはIntelの電力分析ツールで、消費電力の原因を特定し最適化の提案を行います。

# インストール
sudo apt install powertop  # Debian/Ubuntu
sudo dnf install powertop  # Fedora/RHEL

# インタラクティブモードで実行
sudo powertop

# HTMLレポートの生成
sudo powertop --html=powertop-report.html

# 全省電力の自動チューニング
sudo powertop --auto-tune

# キャリブレーション (正確なデータのため数回実行)
sudo powertop --calibrate

# ブート時の自動チューニング用systemdサービスを作成
cat > /etc/systemd/system/powertop-auto-tune.service << 'EOF'
[Unit]
Description=PowerTOP自動チューニング
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/powertop --auto-tune
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable powertop-auto-tune

20.2 turbostat

turbostatはプロセッサのトポロジ、周波数、アイドル電力状態の統計、温度、電力を報告します。

# インストール (linux-toolsの一部)
sudo apt install linux-tools-common linux-tools-$(uname -r)

# 基本的な使用方法
sudo turbostat

# 特定の列を表示
sudo turbostat --show Core,CPU,Avg_MHz,Busy%,Bzy_MHz,TSC_MHz,PkgTmp,PkgWatt,CorWatt

# 特定期間の実行
sudo turbostat --num_iterations 10 --interval 1

# 特定コマンドの監視
sudo turbostat -- stress-ng --cpu 4 --timeout 30

# 出力例:
# Core  CPU  Avg_MHz  Busy%  Bzy_MHz  TSC_MHz  PkgTmp  PkgWatt  CorWatt
# -     -    112      3.12   3592     3600     52      8.45     3.21

20.3 cpupower

cpupowerはCPU周波数とアイドル状態管理のユーティリティです。

# インストール
sudo apt install linux-cpupower  # Debian/Ubuntu
sudo dnf install kernel-tools    # Fedora/RHEL

# CPU周波数情報の表示
cpupower frequency-info

# ガバナーの設定
sudo cpupower frequency-set -g performance

# 周波数範囲の設定
sudo cpupower frequency-set -d 1.2GHz -u 3.6GHz

# アイドル状態情報の表示
cpupower idle-info

# 特定のアイドル状態の無効化
sudo cpupower idle-set -d 3  # 状態3 (C6) を無効化
sudo cpupower idle-set -e 3  # 状態3を再有効化

# 監視モード
sudo cpupower monitor

20.4 TLP

TLPはLinuxラップトップ向けの高度な電力管理ツールです。

# インストール
sudo apt install tlp tlp-rdw  # Debian/Ubuntu

# TLPの起動
sudo tlp start

# フルステータスの表示
sudo tlp-stat

# バッテリー情報の表示
sudo tlp-stat -b

# プロセッサ情報の表示
sudo tlp-stat -p

# 温度情報の表示
sudo tlp-stat -t

# ACモードへの手動切替
sudo tlp ac

# バッテリーモードへの手動切替
sudo tlp bat

20.5 thermald

Intelの自動サーマル管理デーモンです。

# インストール
sudo apt install thermald

# 起動と有効化
sudo systemctl enable --now thermald

# ログの確認
sudo journalctl -u thermald -f

# thermaldは自動的に以下を管理:
# - サーマルゾーンの監視
# - CPU周波数スロットリングの適用
# - intel_powerclampの管理
# - RAPL電力制限の管理
# - ファン速度の制御 (サポート時)

20.6 s2ramと関連ツール

# s2ram: Suspend-to-RAMのテストとデバッグ
sudo apt install uswsusp

# s2ram互換性の確認
sudo s2ram --test

# ワークアラウンド付きサスペンド
sudo s2ram --force
sudo s2ram --vbe_save --vbe_post  # VBE状態の保存/復元

# sleepgraph: 詳細なサスペンド/レジューム分析
sudo sleepgraph -m mem -rtcwake 15 -o /tmp/sleepgraph
# /tmp/sleepgraph/ に詳細なHTMLビジュアライゼーションを作成

20.7 その他のツール

# upower: 電源デバイス情報サービス
upower -i /org/freedesktop/UPower/devices/battery_BAT0
upower -d  # 全情報のダンプ
upower --monitor  # 電源イベントの監視

# acpi: バッテリーとサーマル情報の表示
acpi -V  # 詳細
acpi -b  # バッテリー
acpi -t  # サーマル

# sensors (lm-sensors): ハードウェア監視
sudo apt install lm-sensors
sudo sensors-detect
sensors
# coretemp-isa-0000
# Adapter: ISA adapter
# Package id 0:  +52.0 C  (high = +100.0 C, crit = +100.0 C)
# Core 0:        +48.0 C
# Core 1:        +50.0 C

# stress-ng: 電力分析用ストレステスト
stress-ng --cpu 8 --timeout 60  # CPUストレス
stress-ng --cpu 8 --cpu-method matrixprod --timeout 60  # 特定メソッド

21. ベストプラクティスとトラブルシューティング

21.1 電力管理のベストプラクティス

ラップトップ向け

# 1. 適切な設定でTLPを使用
# 2. 全デバイスのランタイムPMを有効化
# 3. schedutilガバナーを使用
# 4. バッテリー充電しきい値を設定 (40-80%)
# 5. SATA ALPMを有効化
# 6. PCIe ASPMを有効化
# 7. ディスプレイの自動減光/自動オフを設定
# 8. ゲームやストリーミング時以外はWiFi省電力を有効化

# クイックラップトップ最適化スクリプト
#!/bin/bash
echo "=== ラップトップ電力最適化 ==="

# ガバナーの設定
for gov in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
    echo schedutil > "$gov"
done

# 全PCIデバイスのランタイムPMを有効化
for control in /sys/bus/pci/devices/*/power/control; do
    echo auto > "$control"
done

# USBオートサスペンドを有効化
for control in /sys/bus/usb/devices/*/power/control; do
    echo auto > "$control"
done

# オーディオ省電力を有効化
echo 1 > /sys/module/snd_hda_intel/parameters/power_save 2>/dev/null
echo Y > /sys/module/snd_hda_intel/parameters/power_save_controller 2>/dev/null

# NMIウォッチドッグを無効化
echo 0 > /proc/sys/kernel/nmi_watchdog

# ラップトップモードを有効化
echo 5 > /proc/sys/vm/laptop_mode

# ダーティライトバック時間の設定
echo 6000 > /proc/sys/vm/dirty_writeback_centisecs

echo "完了!"

サーバー向け

# 1. ワークロードプロファイルに基づくガバナー選択
# 2. データセンター電力バジェットのRAPLパワーキャッピング
# 3. turbostatとIPMIで電力を監視
# 4. レイテンシ要件に基づくC-stateチューニング
# 5. NUMA考慮スケジューリングの使用
# 6. リアルタイムワークロードの周波数固定を検討

# サーバー電力プロファイリングスクリプト
#!/bin/bash
echo "=== サーバー電力プロファイル ==="
echo "30秒間の電力サンプルを収集中..."

# 開始時RAPLエネルギーを記録
E_START=$(cat /sys/class/powercap/intel-rapl:0/energy_uj)

# 30秒間記録
sudo turbostat --show Avg_MHz,Busy%,PkgWatt,CorWatt,PkgTmp \
    --interval 5 --num_iterations 6

# 終了時RAPLエネルギーを記録
E_END=$(cat /sys/class/powercap/intel-rapl:0/energy_uj)

# 平均電力を計算
ENERGY_J=$(echo "scale=2; ($E_END - $E_START) / 1000000" | bc)
AVG_WATTS=$(echo "scale=2; $ENERGY_J / 30" | bc)
echo ""
echo "総エネルギー: ${ENERGY_J} J"
echo "平均電力: ${AVG_WATTS} W"

21.2 一般的なトラブルシューティング

# 問題: システムがサスペンドしない
# 解決: ブロックしているウェイクアップソースとプロセスを確認
cat /sys/kernel/debug/wakeup_sources | awk '$3 > 0'
ps aux | awk '$8 ~ /D/'
dmesg | grep -i "suspend\|pm:" | tail -20

# 問題: サスペンド後すぐに復帰する
# 解決: 偽のウェイクアップソースを確認して無効化
cat /proc/acpi/wakeup
for src in XHC0 USB0 EHC1; do
    echo $src | sudo tee /proc/acpi/wakeup
done

# 問題: バッテリーでの高消費電力
# 解決: 電力消費者を特定
sudo powertop  # "Tunables"タブで提案を確認

# 問題: CPUが低周波数で固定
# 解決: ガバナーと周波数制限を確認
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
cat /sys/devices/system/cpu/intel_pstate/max_perf_pct

# 問題: サーマルスロットリング
# 解決: サーマルゾーンと冷却デバイスを確認
for zone in /sys/class/thermal/thermal_zone*/; do
    echo "$(cat $zone/type): $(cat $zone/temp 2>/dev/null)m度C"
done
dmesg | grep -i "thermal\|throttl"

# 問題: ハイバネーションが失敗
# 解決: スワップ領域とレジューム設定を確認
swapon --show
cat /proc/cmdline | tr ' ' '\n' | grep resume
free -h  # ハイバネーションにはスワップ >= RAM が必要

# 問題: デバイスがランタイムサスペンドに入らない
cat /sys/devices/.../power/control  # "auto"であるべき
cat /sys/devices/.../power/runtime_status
cat /sys/devices/.../power/runtime_usage  # サスペンドには0であるべき

21.3 監視とアラート

# systemdベースの電力監視タイマー
cat > /etc/systemd/system/power-monitor.service << 'EOF'
[Unit]
Description=電力監視

[Service]
Type=oneshot
ExecStart=/usr/local/bin/power-monitor.sh
EOF

cat > /etc/systemd/system/power-monitor.timer << 'EOF'
[Unit]
Description=電力監視タイマー

[Timer]
OnCalendar=*:*:00/30
Persistent=true

[Install]
WantedBy=timers.target
EOF

cat > /usr/local/bin/power-monitor.sh << 'SCRIPT'
#!/bin/bash
LOG="/var/log/power-monitor.log"
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")

# CPU温度
CPU_TEMP=$(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null)
CPU_TEMP_C=$((CPU_TEMP / 1000))

# RAPL電力
PKG_ENERGY=$(cat /sys/class/powercap/intel-rapl:0/energy_uj 2>/dev/null)

# バッテリー (該当する場合)
BAT_PCT=$(cat /sys/class/power_supply/BAT0/capacity 2>/dev/null || echo "N/A")
BAT_STATUS=$(cat /sys/class/power_supply/BAT0/status 2>/dev/null || echo "N/A")

echo "$TIMESTAMP cpu_temp=${CPU_TEMP_C}C pkg_energy=${PKG_ENERGY}uJ battery=${BAT_PCT}% status=$BAT_STATUS" >> "$LOG"

# 温度が高すぎる場合にアラート
if [ "$CPU_TEMP_C" -gt 90 ]; then
    logger -p daemon.warning "電力アラート: CPU温度 ${CPU_TEMP_C}度Cが90度Cを超過"
fi
SCRIPT

chmod +x /usr/local/bin/power-monitor.sh
sudo systemctl enable --now power-monitor.timer

22. 参考文献

22.1 カーネルドキュメント

  • /Documentation/power/ - Linuxカーネルソースツリー内
  • /Documentation/admin-guide/pm/ - 電力管理管理者ガイド
  • /Documentation/driver-api/pm/ - ドライバPM APIドキュメント
  • /Documentation/ABI/testing/sysfs-power - sysfs PMインターフェース
  • /Documentation/firmware-guide/acpi/ - ACPIドキュメント

22.2 仕様

  • ACPI仕様: https://uefi.org/specifications (ACPI 6.5)
  • PCI電力管理: PCI-SIG PM Specification 1.2
  • USB電力管理: USB 3.x仕様、第9章
  • Intel RAPL: Intel SDM Volume 3、第15章
  • Intel HWP: Intel SDM Volume 3、セクション14.4

22.3 オンラインリソース

22.4 主要ソースファイル

# コアPMフレームワーク
kernel/power/main.c          - メインPMエントリポイント
kernel/power/suspend.c       - システムサスペンド
kernel/power/hibernate.c     - ハイバネーション
kernel/power/snapshot.c      - ハイバネーションスナップショット
drivers/base/power/runtime.c - ランタイムPMコア
drivers/base/power/main.c    - デバイスPMコア

# CPU周波数
drivers/cpufreq/cpufreq.c          - cpufreqコア
drivers/cpufreq/intel_pstate.c      - Intel P-stateドライバ
drivers/cpufreq/amd-pstate.c        - AMD P-stateドライバ
drivers/cpufreq/acpi-cpufreq.c      - ACPI cpufreqドライバ

# CPUアイドル
drivers/cpuidle/cpuidle.c           - cpuidleコア
drivers/cpuidle/governors/menu.c    - Menuガバナー
drivers/cpuidle/governors/teo.c     - TEOガバナー
drivers/idle/intel_idle.c           - Intelアイドルドライバ

# ACPI
drivers/acpi/sleep.c        - ACPIスリープ
drivers/acpi/processor*.c   - ACPIプロセッサ
drivers/acpi/battery.c      - ACPIバッテリー
drivers/acpi/thermal.c      - ACPIサーマル

# サーマル
drivers/thermal/thermal_core.c      - サーマルフレームワークコア
drivers/thermal/gov_step_wise.c     - Step-wiseガバナー
drivers/thermal/gov_power_allocator.c - Power Allocator

# パワーキャッピング
drivers/powercap/intel_rapl_common.c - RAPL共通
drivers/powercap/intel_rapl_msr.c    - RAPL MSRインターフェース

# 電源供給
drivers/power/supply/power_supply_core.c - 電源供給コア

# レギュレータ
drivers/regulator/core.c    - レギュレータフレームワークコア

本ドキュメントは、Linuxカーネル電力管理の包括的な概要を提供します。この分野は常に進化しており、最新の情報についてはカーネルのドキュメントとソースコードを参照することを推奨します。

ドキュメント生成日: 2026年4月