w前回までで「カーネル空間」の「物理メモリ」を消費し過ぎた結果、OS停止に至った可能性があるというところまで突き止めました。今回は、カーネル空間のどの部分を消費し過ぎていたのか、さらには根本的な原因は何だったのかを追求していきます。カーネル空間の物理メモリといっても、まずはどの部分のメモリを消費しているのか把握しなければなりません。これを把握するには/proc/meminfoを見るのが最も簡単です。/proc/meminfoの出力例は以下のようなものでした。@ITalloc_pages()とか関数系を色々調査して、調べるたとのこと。通常のAPIは利用していないが、MemFreeのカウントダウンは行っているのです。MemFreeをカウントダウンさせるような処理は、各種メモリ確保APIよりもローレベルな部分で実装されています。Slabやvmalloc、PageTablesなどもすべて、このMemFreeをカウントダウンさせるような共通関数を利用しています。その関数がalloc_pages()(注3)です。基本的にこの関数はメモリの統計情報のカウント対象にならないため、直接使うことは望ましくないのですが、ソースコードをgrepしてみると、このalloc_pages()を直接呼び出している不届き者は結構います。ドライバのような「一度メモリを確保するともうあまりメモリを必要としない」ルーチンに多く見られます。ほかにも、DMA領域用のメモリ確保など、多くのサブシステムから共通関数として呼び出されています。今回もこのalloc_pages()を直接呼び出している部分を中心的に調べるのがよさそうです。非常に多くの部分で利用されているこの関数の呼び出し元を逐一追っていくのもまた現実的ではありません。@ITすげぇなぁ、ここまで解析。最終的にalloc_pagesとfree_pagesの対応関係が取れていないように見えたのが、NFSから呼び出されているものと、cciss(HP製SMARTアレイのドライバ)から呼び出されているものでした。@ITやっぱり、Changelogは重要wwこれを糸口にしてカーネルのChangeLogを調査してみると、kernel-2.6.10で修正されていることが分かりました(注5)。4はkernel-2.6.9ベースのカーネルで構築されているため、このパッチは取り込まれていません。ccissのデバイスドライバでは、DMAマスクは32bitマスク(4Gbytes)で定義されています。そのため、x86_64かつIOMMU(注6)を持たないCPUで(注7)、物理メモリを4Gbytes以上搭載していると、この事象が発生することになります。今回はx86_64で50Gbytesものメモリを搭載しているため、十分この条件に当てはまりそうです。@ITMemFreeって無くなると時々しますが、大丈夫なんですよねぇ。ScanNetSecurity[国内最大級のサイバーセキュリティ専門ポータルサイト]月別アーカイブはてなブログをはじめよう!ripjyrさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。