SystemTapで真犯人を捕まえろ!(1/4) − @IT(情報元のブックマーク数)
連載最終話、デバッグハックスw、尻尾を捕まえてさらし首→修正→無罪放免w
前回までで「カーネル空間」の「物理メモリ」を消費し過ぎた結果、OS停止に至った可能性があるというところまで突き止めました。今回は、カーネル空間のどの部分を消費し過ぎていたのか、さらには根本的な原因は何だったのかを追求していきます。
SystemTapで真犯人を捕まえろ! (1/4):Linuxトラブルシューティング探偵団 番外編(3) - @IT
カーネル空間の物理メモリといっても、まずはどの部分のメモリを消費しているのか把握しなければなりません。これを把握するには/proc/meminfoを見るのが最も簡単です。/proc/meminfoの出力例は以下のようなものでした。
alloc_pages()とか関数系を色々調査して、調べるたとのこと。
つまり、通常のAPIは利用していないが、MemFreeのカウントダウンは行っているのです。MemFreeをカウントダウンさせるような処理は、各種メモリ確保APIよりもローレベルな部分で実装されています。Slabやvmalloc、PageTablesなどもすべて、このMemFreeをカウントダウンさせるような共通関数を利用しています。その関数がalloc_pages()(注3)です。
SystemTapで真犯人を捕まえろ! (2/4):Linuxトラブルシューティング探偵団 番外編(3) - @IT
基本的にこの関数はメモリの統計情報のカウント対象にならないため、直接使うことは望ましくないのですが、ソースコードをgrepしてみると、このalloc_pages()を直接呼び出している不届き者は結構います。特に、ドライバのような「一度メモリを確保するともうあまりメモリを必要としない」ルーチンに多く見られます。ほかにも、DMA領域用のメモリ確保など、多くのサブシステムから共通関数として呼び出されています。
今回もこのalloc_pages()を直接呼び出している部分を中心的に調べるのがよさそうです。しかし、非常に多くの部分で利用されているこの関数の呼び出し元を逐一追っていくのもまた現実的ではありません。どうすれば問題の根源を見つけることができるのでしょうか……?
すげぇなぁ、ここまで解析。
そして、最終的にalloc_pagesとfree_pagesの対応関係が取れていないように見えたのが、NFSから呼び出されているものと、cciss(HP製SMARTアレイのドライバ)から呼び出されているものでした。
SystemTapで真犯人を捕まえろ! (2/4):Linuxトラブルシューティング探偵団 番外編(3) - @IT
やっぱり、Changelogは重要ww
これを糸口にしてカーネルのChangeLogを調査してみると、kernel-2.6.10で修正されていることが分かりました(注5)。RHEL 4はkernel-2.6.9ベースのカーネルで構築されているため、このパッチは取り込まれていません。
SystemTapで真犯人を捕まえろ! (3/4):Linuxトラブルシューティング探偵団 番外編(3) - @IT
さらに、ccissのデバイスドライバでは、DMAマスクは32bitマスク(4Gbytes)で定義されています。そのため、x86_64かつIOMMU(注6)を持たないCPUで(注7)、物理メモリを4Gbytes以上搭載していると、この事象が発生することになります。今回はx86_64で50Gbytesものメモリを搭載しているため、十分この条件に当てはまりそうです。
MemFreeって無くなると時々しますが、大丈夫なんですよねぇ。(そりゃ本当にまずいとだめだけど
【第1回で覚えておいてほしいこと】
- MemFreeが少なくなることを恐れてはいけない
- freeコマンドの結果は物理メモリ使用量の正確な把握には向かない
- 物理メモリ使用状況把握にはActive、Inactiveを使うべきである
SystemTapで真犯人を捕まえろ! (4/4):Linuxトラブルシューティング探偵団 番外編(3) - @IT【第2回で覚えておいてほしいこと】