tkochiの覚え書き RSSフィード

2007-07-10

[] 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神話をリストアップしておきたいと思います。

  1. There is no benefit to enabling ACPI on my notebook, desktop, or server.
  2. Suspend to Disk doesn't work, it must be ACPI's fault.
  3. The buttons on my notebook don't work, it must be ACPI's fault.
  4. My motherboard boots with acpi=off, but fails otherwise, it must be ACPI's fault.
  5. The Linux community has no influence on the ACPI Specification.
  6. ACPI bugs are all due to substandard platform BIOS.
  7. ACPI code seems to change a lot, but isn't getting any better.
  8. ACPI is slow and thus bad for highperformance cpufreq governors such as "ondemand."
  9. Myth: Speedstep-centrino is native and thus faster than ACPI-based `acpi-cpufreq.'
  10. More CPU idle power states (Cstates) are better than fewer states.
  11. Throttling the CPU will always use less energy and extend battery life.
  12. I can't contribute to improving ACPI in Linux.

[] 神話2: サスペンドが動かないのはACPIのせい?

上の神話の中でももっとも誤解されている、もしくは正しく理解している人が少ないと思われるのがこれです。

ACPI以前のノートPCにはAPM (Advanced Power Management) BIOSというものが搭載されていて、これがサスペンド等の面倒をみていました。*BSDではAPMはそれなりによくサポートされており、蓋を閉じるとサスペンドなどできたりしました。これがACPIだとLinuxですらいまだに完全には動かない、機種によっては動いたり動かなかったりなどという状態です。

これは、APM時代はサスペンド前後のデバイス状態の保存・復帰などをBIOSが面倒を見てくれたためOS用の実装が比較的楽だったのですが、ACPIの場合はすべてOSカーネルドライバが面倒を見る必要があり、それが正しくサポートされていないというのが主な理由です。

なぜ時代が進化したのにこのようにOS側に負担がかかるような仕様になったのかというと、デバイスの状態を一番知っているのはドライバだから、ドライバが状態を保存・復帰するのが一番適当だろう、ということです。

具体的に考えてみましょう。例えば、ディスクにwriteコマンドを発行し、DMA転送を行っている途中でサスペンドの要求がユーザから来たとします。このタイミングでサスペンドしたとすると、このDMA転送は途中で止まるのでしょうか?レジューム後にDMA転送が完了したとすると、割り込みがちゃんと届くのでしょうか?ちょっと考えただけでもOS透過なBIOSだけでのサスペンドは実現は不可能そうです。

ハイバネーション (Suspend-To-Disk) は ACPI BIOS 的には電源断とほぼ同じです。OSサスペンド時に必要な情報を全てディスクに保存し、再起動時にディスクから情報を読んで状態を復帰する必要があります。

サスペンド (Suspend-To-RAM) は、もう少し複雑で、各デバイスの状態の保存・復帰をメモリ上に行うなどは OS 側で行う必要がありますが、

  • RAM以外にも wake up に必要なデバイス (一部のUSBポートやモデムなど) の電源を入れたままにする
  • 再起動時にはメモリ上の特定アドレスに BIOS から実行が移ることに備える

あたりは一部ACPI BIOSの助けを借りることになります。

これ以外にも、デバイスごとに省電力状態が定義されているような場合 (PCIデバイスなど) はOSドライバが面倒を見る必要があります。

ラップトップでのまともなサスペンドハイバネーションのサポートは多くの人が望むことでありながら、多くのチャレンジャーが挫折したと思われるポイントは以下の点です。

ACPIの仕様書は非常に厚い (500ページ以上) のですが、サスペンドハイバネーションに関してはBIOSがほとんど助けてくれることはなく、「この仕様書に目を通せばやり方がわかるのではないか?」と期待を持って読み始めると痛い目に遭うのでした。

このように、ざっと見ただけでもOSにおけるACPIを使ったサスペンドハイバネーションのサポートは非常に複雑かつ面倒であることがわかっていただけるのではないかと思います。つまり、サスペンドができないのはACPI仕様の問題だけでもなく、カーネル内のACPIドライバだけの問題でもありません。

Linuxも*BSDカーネルACPIドライバは単独でディレクトリがあり、その中にドライバのソースが含まれているのですが、その中でどうがんばっても実はサスペンドは実現できないのです。デバイスドライバ全体のフレームワークや、プロセス状態の保存など、カーネルの中核部分についてもかなりの変更が必要なのです。これが、オープンソース系のOSサスペンドがなかなか実現できない最大の理由です。