web-dev-qa-db-ja.com

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

私はグーグルで調べて、ほとんどの人がkmallocの使用を提唱していることを発見しました。あなたは連続したメモリの物理ブロックを取得することが保証されているからです。ただし、必要な連続する物理ブロックが見つからない場合、kmallocが失敗する可能性もあります。
連続したメモリブロックを持つことの利点は何ですか?具体的には、なぜシステムコールで連続した物理メモリブロックが必要なのですか? vmallocを使用できない理由はありますか?
最後に、システムコールの処理中にメモリを割り当てる場合、GFP_ATOMIC?システムコールはアトミックコンテキストで実行されますか?

GFP_ATOMIC
割り当ては優先度が高く、スリープしません。これは、割り込みハンドラー、下半分、およびスリープできない他の状況で使用するフラグです。

GFP_KERNELこれは通常の割り当てであり、ブロックする可能性があります。これは、スリープしても安全な場合にプロセスコンテキストコードで使用するフラグです。

105
FreeMemory

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

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

kmallocは、提供できるバッファーのサイズに制限があります:128 Kバイト*)。本当に大きなバッファーが必要な場合は、vmallocまたはブート時に高メモリを予約するような他のメカニズムを使用する必要があります。

*) これは以前のカーネルにも当てはまりました。最近のカーネル(2.6.33.2でこれをテストしました)では、単一のkmallocの最大サイズは最大4 MBです! (私はかなり これに関する詳細な投稿 を書きました。)— kaiwan

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

85
DGentry

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

真剣に、あなたが理解する必要があるカーネルメモリ管理に関連する多くの微妙な問題があります-私はそれで問題をデバッグすることに多くの時間を費やしています。

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

16
Mike Heinz

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

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

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

12
codetwiddler

kmalloc()vmalloc()関数は、バイトサイズのチャンクでカーネルメモリを取得するためのシンプルなインターフェイスです。

  1. kmalloc()関数は、ページが物理的に連続している(および実質的に連続している)ことを保証します。

  2. vmalloc()関数はkmalloc()と同様の方法で機能しますが、仮想的にのみ連続し、必ずしも物理的に連続していないメモリを割り当てる点が異なります。

10
Yogeesh H T

連続したメモリブロックを持つことの利点は何ですか?具体的には、なぜシステムコールで連続した物理メモリブロックが必要なのですか? vmallocを使用できない理由はありますか?

vmalloc上のGoogleの「I'm Feeling Lucky」から:

非常に大きな領域を必要としない限り、kmallocが好ましい方法です。問題は、DMA from/to some hardware device、you ' kmallocを使用する必要があり、おそらくより大きなチャンクが必要になります。解決策は、メモリが断片化される前に、できるだけ早くメモリを割り当てることです。

5
Dark Shikari

32ビットシステムでは、kmalloc()は、物理アドレスへの直接マッピング(実際は一定のオフセット)を持つカーネル論理アドレス(ただし仮想アドレス)を返します。この直接マッピングにより、連続したRAMの物理チャンクを確実に取得できます。 DMAに適しています。最初のポインタのみを指定し、その後の操作では連続した物理マッピングを期待します。

vmalloc()は、カーネルの仮想アドレスを返します。これは、物理RAMで連続したマッピングを持たない可能性があります。大量のメモリ割り当てや、プロセスに割り当てられたメモリが物理RAMでも連続的であることを気にしない場合に役立ちます。

2
a.saurabh

他の違いの1つは、kmallocが論理アドレスを返すことです(そうでない場合は、GPF_HIGHMEMを指定します)。論理アドレスは「ローメモリ」(物理メモリの最初のギガバイト)に配置され、物理アドレスに直接マップされます(変換するには__paマクロを使用します)。このプロパティは、kmallocedメモリが連続メモリであることを意味します。

一方、Vmallocは「ハイメモリ」から仮想アドレスを返すことができます。これらのアドレスを物理アドレスに直接変換することはできません(virt_to_page関数を使用する必要があります)。

1
Jezz