vmalloc と kmalloc の違いは何ですか?

物理的にアドレス指定されたバス (PCI など) 上の DMA デバイスによってバッファがアクセスされる場合にのみ、物理的に連続したメモリの使用について心配する必要があります。問題は、多くのシステム コールが、バッファが最終的に DMA デバイスに渡されるかどうかを知る方法がないことです。一度バッファを別のカーネル サブシステムに渡すと、それがどこに行くのか本当にわかりません。カーネルが DMA 用のバッファを現在使用していなくても、 将来の開発ではそうなるかもしれません.

vmalloc は、バッファー空間を実質的に連続した範囲に再マップする必要がある場合があるため、kmalloc よりも遅くなることがよくあります。 kmalloc が再マップされることはありませんが、GFP_ATOMIC で呼び出されない場合、kmalloc はブロックされる可能性があります。

kmalloc は、提供できるバッファのサイズに制限があります:128 KBytes *) .非常に大きなバッファが必要な場合は、vmalloc を使用するか、ブート時にハイ メモリを予約するなどの他のメカニズムを使用する必要があります。

GFP_ATOMIC を kmalloc() に渡す必要のないシステム コールの場合は、GFP_KERNEL を使用できます。あなたは割り込みハンドラではありません。アプリケーション コードはトラップによってカーネル コンテキストに入りますが、これは割り込みではありません。


簡単な答え:Linux デバイス ドライバーをダウンロードし、メモリ管理に関する章を読んでください。

真剣に、カーネル メモリ管理に関連して理解しなければならない微妙な問題がたくさんあります。私は多くの時間をカーネル メモリ管理に関する問題のデバッグに費やしています。

vmalloc() はめったに使用されません。これは、カーネルが仮想メモリをめったに使用しないためです。 kmalloc() は通常使用されるものですが、さまざまなフラグの結果が何であるかを知る必要があり、失敗したときに何が起こるかを処理するための戦略が必要です-特に、あなたが提案したように割り込みハンドラーにいる場合.


Robert Love による Linux Kernel Development (第 12 章、第 3 版の 244 ページ) は、これに非常に明確に答えています。

はい、多くの場合、物理的に連続したメモリは必要ありません。カーネルで kmalloc が vmalloc よりも多く使用される主な理由は、パフォーマンスです。この本では、vmalloc を使用して大きなメモリ チャンクが割り当てられる場合、カーネルは物理的に連続していないチャンク (ページ) を単一の連続した仮想メモリ領域にマップする必要があると説明しています。メモリは実質的に連続しており、物理的に連続していないため、いくつかの仮想から物理へのアドレス マッピングをページ テーブルに追加する必要があります。最悪の場合、(バッファーのサイズ/ページ サイズ) になります。 ページ テーブルに追加されたマッピングの数。

これにより、このバッファーにアクセスするときに、TLB (最近の仮想アドレスから物理アドレスへのマッピングを格納するキャッシュ エントリ) に負荷がかかります。これはスラッシングにつながる可能性があります。