4月版 Linus(と筆者)を嘆かせたanon_vma騒ぎ


小崎資広
2010/5/18

rmapスケーラビリティパッチとその混乱

 LinuxにおけるVMの役割の1つに、仮想アドレスと物理アドレスの変換があります。仮想→物理変換は主にページフォルト時の処理のために必要であり、物理→仮想は主にページ回収処理(キャッシュ破棄やスワップアウト)で使われます(ページをfreeにする前に参照しているプロセスのページテーブルエントリを削除しておかないと、カーネルがクラッシュしてしまいます)。

 Larry Woodmanはanonymous memory(注1)用の物理→仮想変換処理がAIM7ベンチマークに大幅な性能劣化を与えていることを報告しました。

 anonymous memoryの物理→仮想変換処理(注2)は、図1のような構造になっています。vm_area_struct、略してVMAが、プロセスの仮想アドレス空間のあるリージョン(オフセットと長さのペア、例えば番地0x10000から1MB)とその属性(アクセス権やさまざまなmmapで与えられたフラグ、mbindで設定されたNUMAバインディングなど)を表しており、その逆マッピングのVMAのリストを保持する管理用構造体がanon_vmaです。

図1 anonymous memoryの物理→仮想変換処理

 一見きれいな構造をしているように見えますが、この構造はfork時にちょっと奇妙な動作をします。図2図3のように、VMAはコピーするがanon_vmaはコピーせず、anon_vmaの持つVMAリストに親子両方のVMAをつなげるのです。

図2 通常時の挙動
図3 fork時のanon_vmaの挙動

 これはCopy-On-Write(以下COW)の仕様が原因です。Linuxはfork時は実際のデータはコピーせず、fork後に最初にメモリにアクセスした時点でデータコピーを行います。これにより、fork後すぐにexecするようなケースを高速化しているのです。

 COWによりコピーされたデータが親子どちらに割り当てられるかは、どちらのプロセスが先にメモリにアクセスするかに依存します。よってfork時には何も決められないので、仕方なく両方をリストにつないでおくのです。

 この方式の欠点は、COWが終わった後明らかになります(図4)。親と子はもはや何もデータを共有していないにもかかわらず同じanon_vmaを共有してしまっているため、ページ回収時のVMAチェックが2倍に増えてしまうのです。そして前述のAIM7は、Larryのconfigでは1万プロセスほどforkするので、メモリ回収時のVMAチェックのコストが普通のシステムの約1万倍になっていたというわけです。

図4 COW終了後の問題点

 そのためRik van Rielによりanon_vma_chainという補助構造体を導入し、図5のようにCOW時に新しいanon_vmaを生成し、もともとのページ群は親子両方のVMAがリンクされている構造を踏襲しつつ、新しいページは必要なVMAだけを参照するよう改良が行われました。

図5 anon_vma_chainによる改良

 この変更は導入当初から、「AIM7は現実のワークロードを全然反映していないから測定方法が不適切ではないか」と指摘され続けていました。さらにマージ後、大量のバグが残っていることが明らかになり、Linus自ら陣頭指揮を執って解決に乗り出すほどの大騒ぎとなりました。

 Linusは当初「このエリアの最近の変更は追えていなかったんだよね、Andrew Mortonに任せっ切りで。ちょうどいい機会だよ」なんて余裕なことをいっていたのですが、VM開発者が現在の動きをいろいろと説明していくにつれ、どんどん楽天的なセリフは減っていきました。

 「は? write lockが取れないからread lock+pte lockで代用してる……だと」
  「は? kfree後のメモリにアクセスする可能性があるけど意図的……だと」
  「は? rmap dereferenceはraceにより全然違うanon_vmaをlookupするかもしれないが仕様……だと」等々……。

 Linusは「このコードは本当に僕を混乱させているよ。ただの人間(mere mortals)にも分かるようにドキュメント化してくれよ」と嘆きました。

注1:プロセスのメモリのうち、ファイルと関連付けられていないメモリ。malloc()で確保したメモリやスタックなど。

注2:仮想→物理の方がよく使われるし素直な変換なので、物理→仮想の変換をreverse mapping(rmap)、つまり逆マッピングということもあります。

2/2

Index
Linux Kernel Watch 4月版
 Linus(と筆者)を嘆かせたanon_vma騒ぎ
  Page 1
アダプティブMutexの最適解は?
Page 2
 rmapスケーラビリティパッチとその混乱

連載 Linux Kernel Watch


 Linux Squareフォーラム Linuxカーネル関連記事
連載:Linux Kernel Watch(連載中)
Linuxカーネル開発の現場ではさまざまな提案や議論が交わされています。その中からいくつかのトピックをピックアップしてお伝えします
連載:Linuxファイルシステム技術解説
ファイルシステムにはそれぞれ特性がある。本連載では、基礎技術から各ファイルシステムの特徴、パフォーマンスを検証する
特集:全貌を現したLinuxカーネル2.6[第1章]
エンタープライズ向けに刷新されたカーネル・コア
ついに全貌が明らかになったカーネル2.6。6月に正式リリースされる予定の次期安定版カーネルの改良点や新機能を詳しく解説する
特集:/procによるLinuxチューニング[前編]
/procで理解するOSの状態

Linuxの状態確認や挙動の変更で重要なのが/procファイルシステムである。/procの概念や/procを利用したOSの状態確認方法を解説する
特集:仮想OS「User Mode Linux」活用法
Linux上で仮想的なLinuxを動かすUMLの仕組みからインストール/管理方法やIPv6などに対応させるカーネル構築までを徹底解説
Linuxのカーネルメンテナは柔軟なシステム
カーネルメンテナが語るコミュニティとIA-64 Linux
IA-64 LinuxのカーネルメンテナであるBjorn Helgaas氏。同氏にLinuxカーネルの開発体制などについて伺った

MONOist組み込み開発フォーラムの中から、Linux関連記事を紹介します


Linux & OSS フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Linux & OSS 記事ランキング

本日 月間