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


113

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

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

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


vmallocおよびkmallocに関する優れた記事http://learnlinuxconcepts.blogspot.in/2014/02/linux-memory-management.html
JIN007

4
その記事は、「一般に32ビットアーキテクチャには4KBのページサイズがあり、64ビットアーキテクチャには8KBのページサイズがある」と言っています。私はそれを完全には読んでいませんが、それを「良い」と言ったり、そこからの言葉を信頼したりすることはありません。
AlexandroSánchez18年

1
注(準関連):vmallocカーネル5.2(2019年第2四半期)の方が高速です
VonC

回答:


96

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

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

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

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

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


1
システムコールは、int $ 0x80をトリガーすることによって入力されたと思いますか?(つまり、割り込み)?
FreeMemory

2
int $ 0x80はソフトウェア割り込みであり、トラップとも呼ばれます。割り込みハンドラとは、ユーザーがキーを押したり、動きを動かしたりするなどのハードウェア割り込みを意味します。
ブラナン2008

システムコールは、ユーザー空間からカーネル空間への移行用です... kmallocはカーネルコンテキストでのみ使用されますか?
AIB

3
@FreeMemory:int $ 0x80はx86固有であり、sysenter / syscall(x86)に取って代わられた古いメソッドでもあります。
ヨルゲンセン

18

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

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

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


1
「カーネルが仮想メモリを使用することはめったにないので」、それはなぜですか?
トレイ

あなたは、一般的に、カーネルのブロックを望んでいないので、それは...内またはディスクストレージのうち、スワップメモリにカーネルを待ちながら
マイク・ハインツ

いいえ、vmallocで割り当てられたカーネルメモリスワップされません。スワップできるのはユーザー空間メモリのみです。カーネルアドレススペースはスワップ不能であり、vmallocはカーネルのアドレススペースに割り当てます。
user2679859

13

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

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

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


11

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

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

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


4

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

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

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


ほら、読んだけど意味がわからない。私はのためkmallocのを使用して理解して大きなエリア。しかし、割り当て量が少ない場合は、物理メモリの断片化を避けるためにvmallocを使用しないのはなぜですか
FreeMemory

カーネルを信頼して最善を尽くす必要があるためです。単一のチャンクを割り当てる方が良いと判断した場合は、そうします。vmallocは、連続したチャンクが絶対に必要な場合にのみ使用します。
Dark Shikari

それは理にかなっていると思いますが、直感に反するようです。kmallocは、パフォーマンスが最大の懸念事項である(つまり、ディスクIOに悩まされない)ときに使用する必要があるように聞こえます。また、GFP_ATOMICはどうですか?
FreeMemory 2008

2

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

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


1

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.