bokumin.org

Github RSS Sitemap Mail
ritual-clearcut

FreeBSDで実際のC-stateを確認する(ACPIテーブル)

Determining C-states using ACPI table analysis on FreeBSD

前回はOpenBSDでdmesgのMWAIT値からC-stateの実態を読み取る方法を紹介しました。今回は同じ疑問をFreeBSDで掘り下げてみた話です。FreeBSDでは sysctl でより詳細な数値が得られるので、ACPIテーブルから直接確認してみました。
※以前の記事はこちらから確認が可能です。

はじめに

OpenBSDとFreeBSDの大きな違いのひとつはC-stateの可視性です。OpenBSDはdmesgを読まないと実態が見えませんが、FreeBSDは sysctl コマンドで直接数値が確認できます。ただし、その数値のラベルが実態を正確に反映しているかどうかは別の話です。今回はそこを確かめていきます。

実行した環境

OS: FreeBSD 14.4-RELEASE
CPU: Intel Xeon E5-2650L v4 (Broadwell-EP)
電力管理: HWPM (OOBモード) 有効

E5-2650L v4はTDPが低く設定されているモデルですが、アイドル時のC-state動作は同世代の他のXeon v4と変わりません。

FreeBSDでのC-state確認

まず sysctl でOSが認識しているC-stateを確認します。

$ sysctl dev.cpu.0.cx_supported
dev.cpu.0.cx_supported: C1/1/1 C2/2/15 C3/2/41

表示の読み方は名前/タイプ/レイテンシ(μs)です。ここで気になるのが C3のレイテンシ「41」 です。一般的なACPI C3の復帰レイテンシは10〜20μs程度とされていますが、41μsはそれより大幅に大きいです。Broadwell-EP世代のC6の標準的な復帰レイテンシと近い値となっていました。

この段階で実際はC6ぽいなあなんて思っていました。前回のOpenBSDと同じ構図です。

ACPIテーブルから実態を確認する

FreeBSDでは acpica-tools を使ってACPIテーブルをダンプ・デコンパイルできます。

ツールの準備

sudo pkg install acpica-tools

ACPIテーブルのダンプと変換

ファイルが多数作成されるので/tmp以下で作業を行いました。

# バイナリ形式でダンプ
sudo acpidump -o acpi_data.bin

# 各テーブルに分割
acpixtract -a acpi_data.bin

# バイナリ(.dat)をASLソース(.dsl)に変換
iasl -d *.dat

変換後、電源管理を定義している ssdt1.dsl の中からレイテンシ値41(16進数で 0x29)を手がかりに検索します。

grep -B 10 "0x29" ssdt1.dsl

発見したASLコード

Register (FFixedHW,
    0x01,               // Bit Width
    0x02,               // Bit Offset
    0x0000000000000020, // Address (MWAIT Hint)
    0x03,               // Access Size
    )
},
0x02,
0x29, // Latency(16進数0x29 = 10進数41)

2つの数値に注目します。

  • MWAIT Hint = 0x20:上位ニブルが 0x2x → C6ステートへの移行を意味します(前回のOpenBSD記事と同じ読み方です)
  • Latency = 0x29(= 41)sysctl が報告していた値と完全に一致

これにより、FreeBSDが「C3」と表示しているステートは、ハードウェアレベルではC6への命令(MWAIT 0x20)が送られていることが確認できました。OpenBSDで 0x21 を確認したときと同じ構造です。

MWAITヒント値の早見表

前回の記事でも触れましたが、改めて整理します。

ヒント値(上位)対応するIntel実装のC-state
0x0xC1-state
0x1xC3-state
0x2xC6-state
0x3xC7-state

OSが表示する「C1/C2/C3」というラベルはACPI規格上の分類であり、実際にハードウェアへ送られる命令(MWAITヒント)とは別物です。この点はIntelのSDMにも明記されています。

補足 HWPMについて

今回の環境では HWPM(Hardware P-State Management)をOOBモードで有効化しています。このモードではCPU自身がP-state(動作周波数)を自律的に制御するため、dmesgに est(Enhanced SpeedStep)ドライバのアタッチエラーが出ることがありますが、これは正常な挙動です。

FreeBSDはLinuxの intel_pstate ドライバに相当するHWPM完全対応実装を持っていないため、OOBモード(OSが介入しない完全ハードウェア自律制御)が現実的な選択になります。NativeモードはFreeBSDでpowerdが動いているとシングルユーザーモードでしか起動しないケースも確認しているため、FreeBSDで使うならOOBのほうが無難です。

まとめ

FreeBSDでは sysctl dev.cpu.0.cx_supported のレイテンシ値が手がかりになります。その値が伝統的なACPI C3(10〜20μs)より大きい場合、ACPIテーブルを掘り下げることで実態が見えてきます。

  • OSの表示名(C1/C2/C3)はあくまでACPIラベル
  • 実際の命令はMWAITヒント値で決まる
  • ヒント値の上位ニブルがC6(0x2x)なら、十分に深い省電力状態に入っている
  • ACPIテーブルのダンプはFreeBSDでも acpica-tools で手軽に行える

OpenBSDはdmesgを読むだけで済みましたが、FreeBSDはsysctlとACPIテーブルという二段構えで、より深く確認できるという違いがあります。誰かの参考になれば幸いです。

おわり

参考URL