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-toolsACPIテーブルのダンプと変換
ファイルが多数作成されるので/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 |
| 0x0x | C1-state |
| 0x1x | C3-state |
| 0x2x | C6-state |
| 0x3x | C7-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
- Intel® 64 and IA-32 Architectures Software Developer’s Manual (Volume 2B: MWAIT instruction)
- github: Linux Kernel Source: intel_idle.c (Broadwell C-states definition)
- Linux Kernel Documentation: CPU Idle Time Management
- FreeBSD man: sysctl(8), acpidump(8)などなど
- OpenBSDで実際のC-stateを確認する(MWAIT)(前回の記事)