Was ist der Unterschied zwischen vmalloc und kmalloc?

Lesezeit: 8 Minuten

Benutzeravatar von FreeMemory
Freier Speicher

Ich habe herumgegoogelt und die meisten Leute gefunden, die die Verwendung von befürworten kmalloc, da Sie garantiert zusammenhängende physische Speicherblöcke erhalten. Allerdings scheint es auch so kmalloc kann fehlschlagen, wenn eine zusammenhängende körperlich Der gewünschte Block kann nicht gefunden werden.
Was sind die Vorteile eines zusammenhängenden Speicherblocks? Genauer gesagt, warum sollte ich eine zusammenhängende haben müssen körperlich Speicherblock in a Systemaufruf? Gibt es einen Grund, warum ich nicht einfach verwenden könnte vmalloc?
Wenn ich schließlich während der Bearbeitung eines Systemaufrufs Speicher zuweisen würde, sollte ich angeben GFP_ATOMIC? Wird ein Systemaufruf in einem atomaren Kontext ausgeführt?

GFP_ATOMIC

Die Zuordnung hat hohe Priorität und schläft nicht. Dies ist das Flag, das in Interrupt-Handlern, unteren Hälften und anderen Situationen verwendet werden muss, in denen Sie nicht schlafen können.

GFP_KERNEL

Dies ist eine normale Zuordnung und kann blockieren. Dies ist das Flag, das im Prozesskontextcode verwendet werden muss, wenn der Ruhezustand sicher ist.

  • Ein guter Artikel über vmalloc und kmalloc http://learnlinuxconcepts.blogspot.in/2014/02/linux-memory-management.html

    – JIN007

    15. Februar 2014 um 15:35 Uhr


  • Dieser Artikel behauptet Unsinn wie: “Im Allgemeinen hat eine 32-Bit-Architektur eine Seitengröße von 4 KB und eine 64-Bit-Architektur eine Seitengröße von 8 KB”. Ich habe es nicht vollständig gelesen, aber ich würde es nicht als “gut” bezeichnen oder ihm auch nur ein Wort trauen.

    – Alexandro Sanchez

    28. Oktober 2018 um 22:00 Uhr

  • Hinweis (halb verwandt): vmalloc ist schneller mit Kernel 5.2 (Q2 2019)

    – VonC

    20. Mai 2019 um 16:05 Uhr

  • Können wir verwenden GFP_NOWAIT Anstatt von GFP_ATOMIC im Interrupt-Kontext? Was ist der eigentliche Unterschied?

    – Roi

    28. Juli um 10:46 Uhr


Benutzeravatar von DGentry
DGentry

Sie müssen sich nur um die Verwendung von physisch zusammenhängendem Speicher kümmern, wenn auf den Puffer von einem DMA-Gerät auf einem physisch adressierten Bus (wie PCI) zugegriffen wird. Das Problem ist, dass viele Systemaufrufe nicht wissen können, ob ihr Puffer schließlich an ein DMA-Gerät übergeben wird: Sobald Sie den Puffer an ein anderes Kernel-Subsystem übergeben, können Sie wirklich nicht wissen, wohin er gehen wird. Auch wenn der Kernel den Puffer nicht für DMA verwendet heute, eine zukünftige Entwicklung könnte dies tun.

vmalloc ist oft langsamer als kmalloc, da es möglicherweise den Pufferspeicher in einen praktisch zusammenhängenden Bereich neu abbilden muss. kmalloc wird niemals neu zugeordnet, obwohl kmalloc blockieren kann, wenn es nicht mit GFP_ATOMIC aufgerufen wird.

kmalloc ist in der Größe des Puffers, den es bereitstellen kann, begrenzt: 128 KBytes*). Wenn Sie einen wirklich großen Puffer benötigen, müssen Sie vmalloc oder einen anderen Mechanismus wie das Reservieren von viel Speicher beim Booten verwenden.

*) Dies galt für frühere Kernel. Bei neueren Kerneln (ich habe dies auf 2.6.33.2 getestet) beträgt die maximale Größe eines einzelnen kmalloc bis zu 4 MB! (Ich schrieb eine ziemlich ausführlicher Beitrag dazu.) — Kaiwan

Für einen Systemaufruf müssen Sie GFP_ATOMIC nicht an kmalloc() übergeben, Sie können GFP_KERNEL verwenden. Sie sind kein Interrupt-Handler: Der Anwendungscode tritt über einen Trap in den Kernel-Kontext ein, es ist kein Interrupt.

  • Ich dachte, Systemaufrufe wurden durch Auslösen von int $0x80 eingegeben? (dh ein Interrupt)?

    – Freier Speicher

    22. September 2008 um 19:01 Uhr

  • int $0x80 ist ein Software-Interrupt, auch Trap genannt. Was mit Interrupt-Handlern gemeint ist, ist ein Hardware-Interrupt, z. B. wenn der Benutzer eine Taste drückt oder die Bewegungen bewegt.

    – Branan

    22. September 2008 um 19:21 Uhr

  • Systemaufrufe sind für Übergänge vom Userspace zum Kernelspace … kmalloc wird nur im Kernelkontext verwendet??

    – AIB

    2. Juli 2009 um 9:28 Uhr

  • @FreeMemory: int $0x80 ist x86-spezifisch, und dann ist es auch eine alte Methode, die durch sysenter/syscall (auf x86) ersetzt wird.

    – Jörgensen

    13. März 2012 um 23:29 Uhr

  • Danke für eine Antwort, die Einblicke gibt. vmalloc ordnet Seite für Seite die virtuellen den physischen Seiten zu. Als Sie sagten, dass kmalloc niemals neu zugeordnet wird, was meinen Sie damit? Hat der Kernel eine vorab zugewiesene virtuell-physikalische Region für kmalloc (zusammenhängend zugewiesen)?

    – Chan-Kim

    1. September 2020 um 6:44 Uhr

Kurze Antwort: herunterladen Linux-Gerätetreiber und lesen Sie das Kapitel über die Speicherverwaltung.

Im Ernst, es gibt viele subtile Probleme im Zusammenhang mit der Kernel-Speicherverwaltung, die Sie verstehen müssen – ich verbringe viel Zeit damit, Probleme damit zu debuggen.

vmalloc() wird sehr selten verwendet, da der Kernel selten virtuellen Speicher verwendet. kmalloc() wird normalerweise verwendet, aber Sie müssen wissen, welche Konsequenzen die verschiedenen Flags haben, und Sie brauchen eine Strategie für den Umgang mit dem, was passiert, wenn es fehlschlägt – insbesondere, wenn Sie sich in einem Interrupt-Handler befinden, wie Sie vorgeschlagen haben.

  • “weil der Kernel selten virtuellen Speicher verwendet”, warum ist das so?

    – Trei

    14. November 2017 um 20:42 Uhr

  • Weil Sie im Allgemeinen nicht möchten, dass der Kernel blockiert, während er darauf wartet, dass der Kernel Speicher in oder aus dem Festplattenspeicher austauscht …

    – Mike Heinz

    1. April 2019 um 23:06 Uhr

  • Nein, Kernelspeicher, der mit vmalloc zugewiesen wurde, ist noch nie getauscht. Nur Userspace-Speicher kann ausgetauscht werden. Der Kernel-Adressraum ist nicht austauschbar und vmalloc weist im Adressraum des Kernels zu.

    – Benutzer2679859

    27. Februar 2020 um 20:22 Uhr

Linux Kernel Development von Robert Love (Kapitel 12, Seite 244 in 3. Auflage) beantwortet dies sehr deutlich.

Ja, in vielen Fällen ist kein physisch zusammenhängender Speicher erforderlich. Der Hauptgrund dafür, dass kmalloc mehr als vmalloc im Kernel verwendet wird, ist die Leistung. Das Buch erklärt, wenn große Speicherblöcke mit vmalloc zugewiesen werden, muss der Kernel die physisch nicht zusammenhängenden Blöcke (Seiten) in eine einzige zusammenhängende virtuelle Speicherregion abbilden. Da der Speicher virtuell zusammenhängend und physikalisch nicht zusammenhängend ist, müssen der Seitentabelle mehrere Zuordnungen von virtuellen zu physikalischen Adressen hinzugefügt werden. Und im schlimmsten Fall wird es sie geben (Puffergröße/Seitengröße) Anzahl der Zuordnungen, die der Seitentabelle hinzugefügt wurden.

Dies erhöht auch den Druck auf den TLB (die Cache-Einträge, die die jüngsten Zuordnungen von virtuellen zu physischen Adressen speichern), wenn auf diesen Puffer zugegriffen wird. Dies kann dazu führen Prügel.

Benutzeravatar von Yogeesh HT
Yogeesh HT

Das kmalloc() & vmalloc() Funktionen sind eine einfache Schnittstelle, um Kernel-Speicher in bytegroßen Blöcken zu erhalten.

  1. Das kmalloc() Funktion garantiert, dass die Seiten physisch zusammenhängend (und virtuell zusammenhängend) sind.

  2. Das vmalloc() Die Funktion funktioniert ähnlich wie kmalloc()außer dass Speicher zugewiesen wird, der nur virtuell zusammenhängend und nicht unbedingt physisch zusammenhängend ist.

Was sind die Vorteile eines zusammenhängenden Speicherblocks? Warum sollte ich insbesondere einen zusammenhängenden physischen Speicherblock in einem Systemaufruf haben? Gibt es einen Grund, warum ich nicht einfach vmalloc verwenden könnte?

Ab Googles “I’m Feeling Lucky”. vmalloc:

kmalloc ist der bevorzugte Weg, solange Sie keine sehr großen Flächen benötigen. Das Problem ist, wenn Sie DMA von/zu einem Hardwaregerät ausführen möchten, müssen Sie kmalloc verwenden, und Sie benötigen wahrscheinlich einen größeren Chunk. Die Lösung besteht darin, Speicher so schnell wie möglich zuzuweisen, bevor der Speicher fragmentiert wird.

  • Sehen Sie, ich habe das gelesen, und es ergibt für mich keinen Sinn. Ich verstehe die Verwendung von kmalloc für groß Bereiche; aber warum nicht für kleine Zuordnungen vmalloc verwenden, um eine Fragmentierung des physischen Speichers zu vermeiden?

    – Freier Speicher

    22. September 2008 um 17:54 Uhr

  • Weil Sie darauf vertrauen sollten, dass der Kernel das Beste tut; Wenn es der Meinung ist, dass die Zuweisung eines einzelnen Chunks besser ist, wird es dies tun. vmalloc ist nur für wenn Sie absolut muss einen zusammenhängenden Brocken haben.

    – Dunkles Shikari

    22. September 2008 um 17:58 Uhr

  • Ich denke, das macht Sinn, aber es scheint kontraintuitiv zu sein. kmalloc hört sich so an, als ob es verwendet werden sollte, wenn die Leistung von größter Bedeutung ist (dh ich kann nicht von Festplatten-IO geplagt werden). Und was ist mit GFP_ATOMIC?

    – Freier Speicher

    22. September 2008 um 18:00 Uhr

Benutzeravatar von a.saurabh
a.saurabh

Auf einem 32-Bit-System gibt kmalloc() die logische Adresse des Kernels zurück (es ist jedoch eine virtuelle Adresse), die die direkte Zuordnung (eigentlich mit konstantem Offset) zur physischen Adresse hat. Diese direkte Zuordnung stellt sicher, dass wir einen zusammenhängenden physischen RAM-Block erhalten. Geeignet für DMA, wo wir nur den Anfangszeiger geben und danach eine zusammenhängende physikalische Abbildung für unsere Operation erwarten.

vmalloc() gibt die virtuelle Kerneladresse zurück, die ihrerseits möglicherweise keine zusammenhängende Zuordnung zum physischen RAM hat. Nützlich für große Speicherzuweisungen und in Fällen, in denen es uns egal ist, dass der unserem Prozess zugewiesene Speicher auch im physischen RAM kontinuierlich ist.

  • Sehen Sie, ich habe das gelesen, und es ergibt für mich keinen Sinn. Ich verstehe die Verwendung von kmalloc für groß Bereiche; aber warum nicht für kleine Zuordnungen vmalloc verwenden, um eine Fragmentierung des physischen Speichers zu vermeiden?

    – Freier Speicher

    22. September 2008 um 17:54 Uhr

  • Weil Sie darauf vertrauen sollten, dass der Kernel das Beste tut; Wenn es der Meinung ist, dass die Zuweisung eines einzelnen Chunks besser ist, wird es dies tun. vmalloc ist nur für wenn Sie absolut muss einen zusammenhängenden Brocken haben.

    – Dunkles Shikari

    22. September 2008 um 17:58 Uhr

  • Ich denke, das macht Sinn, aber es scheint kontraintuitiv zu sein. kmalloc hört sich so an, als ob es verwendet werden sollte, wenn die Leistung von größter Bedeutung ist (dh ich kann nicht von Festplatten-IO geplagt werden). Und was ist mit GFP_ATOMIC?

    – Freier Speicher

    22. September 2008 um 18:00 Uhr

Einer der anderen Unterschiede ist, dass kmalloc eine logische Adresse zurückgibt (andernfalls geben Sie GPF_HIGHMEM an). Logische Adressen werden im “Low Memory” (im ersten Gigabyte des physischen Speichers) platziert und direkt physischen Adressen zugeordnet (verwenden Sie das __pa-Makro, um es zu konvertieren). Diese Eigenschaft impliziert, dass kmzugewiesener Speicher kontinuierlicher Speicher ist.

Andererseits ist Vmalloc in der Lage, virtuelle Adressen aus “hohem Speicher” zurückzugeben. Diese Adressen können nicht direkt in physische Adressen konvertiert werden (Sie müssen die Funktion virt_to_page verwenden).

1423100cookie-checkWas ist der Unterschied zwischen vmalloc und kmalloc?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy