Ich habe herumgegoogelt und festgestellt, dass die meisten Leute die Verwendung von befürworten kmalloc
, da Sie garantiert zusammenhängende physische Speicherblöcke erhalten. Es scheint jedoch auch so, als ob kmalloc
es fehlschlagen kann, wenn ein zusammenhängender physischer Block, den Sie möchten, nicht gefunden werden kann.
Was sind die Vorteile eines zusammenhängenden Speicherblocks? Warum sollte ich in einem Systemaufruf einen zusammenhängenden physischen Speicherblock benötigen ? Gibt es einen Grund, den ich nicht einfach benutzen könnte ?
Wenn ich schließlich während der Bearbeitung eines Systemaufrufs Speicher zuweisen sollte, sollte ich angeben ? Wird ein Systemaufruf in einem atomaren Kontext ausgeführt?vmalloc
GFP_ATOMIC
GFP_ATOMIC
Die Zuweisung hat hohe Priorität und schläft nicht. Dies ist das Flag, das in Interrupt-Handlern, unteren Hälften und anderen Situationen verwendet wird, 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 soll, wenn der Schlaf sicher ist.
quelle
vmalloc
ist schneller mit Kernel 5.2 (Q2 2019)Antworten:
Sie müssen sich nur um die Verwendung eines physisch zusammenhängenden Speichers kümmern, wenn ein DMA-Gerät auf einem physisch adressierten Bus (wie PCI) auf den Puffer zugreift. Das Problem ist, dass viele Systemaufrufe nicht wissen können, ob ihr Puffer irgendwann 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. Selbst wenn der Kernel den Puffer heute nicht für DMA verwendet , könnte eine zukünftige Entwicklung dies tun.
vmalloc ist häufig langsamer als kmalloc, da der Pufferraum möglicherweise in einen praktisch zusammenhängenden Bereich neu zugeordnet werden muss. kmalloc wird nie neu zugeordnet, aber wenn es nicht mit GFP_ATOMIC aufgerufen wird, kann kmalloc blockieren.
kmalloc ist in der Größe des Puffers begrenzt, den es bereitstellen kann: 128 KByte *) . Wenn Sie einen wirklich großen Puffer benötigen, müssen Sie vmalloc oder einen anderen Mechanismus verwenden, z. B. das Reservieren von hohem Speicher beim Booten.
Für einen Systemaufruf müssen Sie GFP_ATOMIC nicht an kmalloc () übergeben, sondern können GFP_KERNEL verwenden. Sie sind kein Interrupt-Handler: Der Anwendungscode gelangt über einen Trap in den Kernel-Kontext, es handelt sich nicht um einen Interrupt.
quelle
Kurze Antwort: Laden Sie die Linux-Gerätetreiber herunter und lesen Sie das Kapitel zur 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 die Konsequenzen der verschiedenen Flags kennen und eine Strategie benötigen, um zu behandeln, was passiert, wenn es fehlschlägt - insbesondere, wenn Sie sich in einem Interrupt-Handler befinden, wie Sie vorgeschlagen haben.
quelle
Die Linux-Kernel-Entwicklung von Robert Love (Kapitel 12, Seite 244 in der 3. Ausgabe) beantwortet dies sehr deutlich.
Ja, in vielen Fällen ist kein physisch zusammenhängender Speicher erforderlich. Der Hauptgrund dafür, dass kmalloc im Kernel häufiger als vmalloc verwendet wird, ist die Leistung. Das Buch erklärt, dass der Kernel, wenn große Speicherblöcke mit vmalloc zugewiesen werden, die physisch nicht zusammenhängenden Blöcke (Seiten) einem einzelnen zusammenhängenden virtuellen Speicherbereich zuordnen muss. Da der Speicher praktisch zusammenhängend und physisch nicht zusammenhängend ist, müssen der Seitentabelle mehrere Zuordnungen von virtuellen zu physischen Adressen hinzugefügt werden. Und im schlimmsten Fall wird der Seitentabelle eine Anzahl von Zuordnungen hinzugefügt (Größe des Puffers / Seitengröße) .
Dies erhöht auch den Druck auf TLB (die Cache-Einträge, in denen die letzten Zuordnungen von virtuellen zu physischen Adressen gespeichert sind), wenn auf diesen Puffer zugegriffen wird. Dies kann zu Schlägen führen .
quelle
Die
kmalloc()
&vmalloc()
-Funktionen sind eine einfache Schnittstelle zum Abrufen des Kernelspeichers in Byte-großen Blöcken.Die
kmalloc()
Funktion garantiert, dass die Seiten physisch zusammenhängend (und praktisch zusammenhängend) sind.Die
vmalloc()
Funktion funktioniert ähnlich wie,kmalloc()
weist jedoch Speicher zu, der nur praktisch zusammenhängend und nicht unbedingt physisch zusammenhängend ist.quelle
Was sind die Vorteile eines zusammenhängenden Speicherblocks? Warum sollte ich in einem Systemaufruf einen zusammenhängenden physischen Speicherblock benötigen? Gibt es einen Grund, warum ich vmalloc nicht einfach verwenden konnte?
Ab Googles "Ich fühle mich glücklich"
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 Block. Die Lösung besteht darin, Speicher so schnell wie möglich zuzuweisen, bevor der Speicher fragmentiert wird.
quelle
Auf einem 32-Bit-System gibt kmalloc () die logische Kerneladresse (es ist jedoch eine virtuelle Adresse) zurück, die die direkte Zuordnung (tatsächlich mit konstantem Versatz) zur physischen Adresse aufweist. Diese direkte Zuordnung stellt sicher, dass wir einen zusammenhängenden physischen Teil des Arbeitsspeichers erhalten. Geeignet für DMA, wo wir nur den Anfangszeiger angeben und danach eine zusammenhängende physische Zuordnung für unseren Betrieb erwarten.
vmalloc () gibt die virtuelle Kerneladresse zurück, die wiederum möglicherweise keine zusammenhängende Zuordnung zum physischen RAM aufweist. 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.
quelle
Einer der anderen Unterschiede ist, dass kmalloc die logische Adresse zurückgibt (andernfalls geben Sie GPF_HIGHMEM an). Logische Adressen werden im "niedrigen Speicher" (im ersten Gigabyte des physischen Speichers) abgelegt und direkt physischen Adressen zugeordnet (verwenden Sie das Makro __pa, um sie zu konvertieren). Diese Eigenschaft impliziert, dass der zugewiesene km-Speicher ein kontinuierlicher Speicher ist.
Andererseits kann Vmalloc virtuelle Adressen aus "hohem Speicher" zurückgeben. Diese Adressen können nicht direkt in physische Adressen konvertiert werden (Sie müssen die Funktion virt_to_page verwenden).
quelle