2007-07-10
■[ACPI] ACPIに関する神話と現実
今年はOttawa Linux Symposiumに行ってきました。
様々な話題についての論文発表やBOFがありましたが、Len BrownのACPI in Linux - Myths vs. Realityという発表が非常に印象に残りました。ACPIというのがAdvanced Configuration and Power Interfaceの略であることや、BIOS仕様についての名前であることや、電源管理等に関連があることは多少PCに詳しい人ならご存じだと思いますが、Linuxや*BSDのカーネル開発者ならよく知っているかというとそうでもないというのが現実です。今回のプレゼンはそういう人のための啓蒙活動と言えます。もっとも、こういうものが出てくるのが遅すぎたという気もしないでもありません。
私もNetBSDではACPIが守備範囲ということになっていますが、同じような質問ばかりにうんざりしていました。やはり一人の頭の中にノウハウが蓄積されているだけではダメで、こういったわかりやすい形で説明するのが非常に重要だと再認識させられました。
これから少しずつ過去の経験で得たノウハウを書いていきたいと思っているのですが、まずは今回のLen Brownの論文に出てくるACPI神話をリストアップしておきたいと思います。
- There is no benefit to enabling ACPI on my notebook, desktop, or server.
- Suspend to Disk doesn't work, it must be ACPI's fault.
- The buttons on my notebook don't work, it must be ACPI's fault.
- My motherboard boots with acpi=off, but fails otherwise, it must be ACPI's fault.
- The Linux community has no influence on the ACPI Specification.
- ACPI bugs are all due to substandard platform BIOS.
- ACPI code seems to change a lot, but isn't getting any better.
- ACPI is slow and thus bad for highperformance cpufreq governors such as "ondemand."
- Myth: Speedstep-centrino is native and thus faster than ACPI-based `acpi-cpufreq.'
- More CPU idle power states (Cstates) are better than fewer states.
- Throttling the CPU will always use less energy and extend battery life.
- I can't contribute to improving ACPI in Linux.
■[ACPI] 神話2: サスペンドが動かないのはACPIのせい?
上の神話の中でももっとも誤解されている、もしくは正しく理解している人が少ないと思われるのがこれです。
ACPI以前のノートPCにはAPM (Advanced Power Management) BIOSというものが搭載されていて、これがサスペンド等の面倒をみていました。*BSDではAPMはそれなりによくサポートされており、蓋を閉じるとサスペンドなどできたりしました。これがACPIだとLinuxですらいまだに完全には動かない、機種によっては動いたり動かなかったりなどという状態です。
これは、APM時代はサスペンド前後のデバイス状態の保存・復帰などをBIOSが面倒を見てくれたためOS用の実装が比較的楽だったのですが、ACPIの場合はすべてOSカーネル・ドライバが面倒を見る必要があり、それが正しくサポートされていないというのが主な理由です。
なぜ時代が進化したのにこのようにOS側に負担がかかるような仕様になったのかというと、デバイスの状態を一番知っているのはドライバだから、ドライバが状態を保存・復帰するのが一番適当だろう、ということです。
- 誰かがサスペンドしようとしたときのデバイスの状態を全て保存しなければならない
- しかし、デバイスの状態はOSのドライバしか知らない、BIOS側からドライバの状態を知るのは困難
- デバイスの操作を全てBIOS経由にするというのは現実的ではない
具体的に考えてみましょう。例えば、ディスクにwriteコマンドを発行し、DMA転送を行っている途中でサスペンドの要求がユーザから来たとします。このタイミングでサスペンドしたとすると、このDMA転送は途中で止まるのでしょうか?レジューム後にDMA転送が完了したとすると、割り込みがちゃんと届くのでしょうか?ちょっと考えただけでもOS透過なBIOSだけでのサスペンドは実現は不可能そうです。
ハイバネーション (Suspend-To-Disk) は ACPI BIOS 的には電源断とほぼ同じです。OS はサスペンド時に必要な情報を全てディスクに保存し、再起動時にディスクから情報を読んで状態を復帰する必要があります。
サスペンド (Suspend-To-RAM) は、もう少し複雑で、各デバイスの状態の保存・復帰をメモリ上に行うなどは OS 側で行う必要がありますが、
あたりは一部ACPI BIOSの助けを借りることになります。
これ以外にも、デバイスごとに省電力状態が定義されているような場合 (PCIデバイスなど) はOSドライバが面倒を見る必要があります。
ラップトップでのまともなサスペンド・ハイバネーションのサポートは多くの人が望むことでありながら、多くのチャレンジャーが挫折したと思われるポイントは以下の点です。
- ACPIの仕様書が厚くて (500ページ以上)、読み切れない
- ACPIの仕様書に目を通してみたがどうやってサスペンド・ハイバネーションをしていいかわからない
- サスペンドにはAMLが関係あるのではないかとそのあたりをうろうろして泥沼にはまる
- 実はACPIの仕様書を読んでもサスペンド・ハイバネーションはOSカーネル側の負担が非常に大きいことに気がつく
ACPIの仕様書は非常に厚い (500ページ以上) のですが、サスペンド・ハイバネーションに関してはBIOSがほとんど助けてくれることはなく、「この仕様書に目を通せばやり方がわかるのではないか?」と期待を持って読み始めると痛い目に遭うのでした。
このように、ざっと見ただけでもOSにおけるACPIを使ったサスペンド・ハイバネーションのサポートは非常に複雑かつ面倒であることがわかっていただけるのではないかと思います。つまり、サスペンドができないのはACPI仕様の問題だけでもなく、カーネル内のACPIドライバだけの問題でもありません。
Linuxも*BSDもカーネルのACPIドライバは単独でディレクトリがあり、その中にドライバのソースが含まれているのですが、その中でどうがんばっても実はサスペンドは実現できないのです。デバイスドライバ全体のフレームワークや、プロセス状態の保存など、カーネルの中核部分についてもかなりの変更が必要なのです。これが、オープンソース系のOSでサスペンドがなかなか実現できない最大の理由です。