125

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

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

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

4

8 に答える 8

106

バッファが物理的にアドレス指定されたバス(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を使用できます。あなたは割り込みハンドラーではありません。アプリケーションコードはトラップを使用してカーネルコンテキストに入ります。これは割り込みではありません。

于 2008-09-22T18:05:22.613 に答える
18

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

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

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

于 2008-09-22T18:05:11.383 に答える
16

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

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

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

于 2012-07-11T22:37:55.803 に答える
14

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

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

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

于 2015-11-30T10:38:44.197 に答える
4

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

Google の "I'm Feeling Lucky" からvmalloc:

非常に大きな領域を必要としない限り、kmalloc が推奨される方法です。問題は、ハードウェア デバイスとの間で DMA を実行する場合、kmalloc を使用する必要があり、おそらくより大きなチャンクが必要になることです。解決策は、メモリが断片化する前に、できるだけ早くメモリを割り当てることです。

于 2008-09-22T17:48:13.280 に答える
1

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

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

于 2012-03-12T06:26:37.300 に答える