Speicherlimit des Linux-Kernels

12

Ich habe ein verblüffendes Problem. Ich habe eine Bibliothek , die verwendet sg zur Ausführung angepasst CDB. Es gibt einige Systeme, die routinemäßig Probleme mit der Speicherzuweisung in sg haben . Normalerweise hat der SG- Treiber ein hartes Limit von ca. 4 MB, aber wir sehen es auf diesen wenigen Systemen mit ~ 2,3 MB Anfragen. Das heißt, die CDBs bereiten sich auf eine Übertragung von 2,3 MB vor. Hier sollte es keine Probleme geben: 2.3 <4.0.

Nun das Profil der Maschine. Es handelt sich um eine 64-Bit-CPU, auf der jedoch CentOS 6.0 32-Bit ausgeführt wird (ich habe sie weder erstellt noch habe ich etwas mit dieser Entscheidung zu tun). Die Kernel-Version für diese CentOS-Distribution ist 2.6.32. Sie haben 16 GB RAM.

Hier sehen Sie, wie die Speichernutzung auf dem System aussieht (da dieser Fehler während des automatisierten Tests auftritt, habe ich noch nicht überprüft, ob dies den Status widerspiegelt, in dem dieser Fehler von sg zurückgegeben wird ).

top - 00:54:46 up 5 days, 22:05,  1 user,  load average: 0.00, 0.01, 0.21
Tasks: 297 total,   1 running, 296 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  15888480k total,  9460408k used,  6428072k free,   258280k buffers
Swap:  4194296k total,        0k used,  4194296k free,  8497424k cached

Ich habe diesen Artikel aus dem Linux Journal gefunden, in dem es um die Zuweisung von Speicher im Kernel geht. Der Artikel ist datiert, scheint sich aber auf 2.6 zu beziehen (einige Kommentare zum Autor an der Spitze). Der Artikel erwähnt, dass der Kernel auf ungefähr 1 GB Speicher begrenzt ist (obwohl es aus dem Text nicht ganz klar ist, ob diese jeweils 1 GB für physisch und virtuell oder insgesamt sind). Ich frage mich, ob dies eine genaue Aussage für 2.6.32 ist. Letztendlich frage ich mich, ob diese Systeme diese Grenze erreichen.

Obwohl dies keine wirkliche Antwort auf mein Problem ist, frage ich mich, ob die Behauptung für 2.6.32 wahr ist. Was ist dann die tatsächliche Speichergrenze für den Kernel? Dies muss möglicherweise bei der Fehlerbehebung berücksichtigt werden. Alle anderen Vorschläge sind willkommen. Was dies so verwirrend macht, ist, dass diese Systeme mit vielen anderen identisch sind, die nicht dasselbe Problem aufweisen.

Andrew Falanga
quelle

Antworten:

21

Das 1-GiB-Limit für den Linux-Kernel-Speicher in einem 32-Bit-System ist eine Folge der 32-Bit-Adressierung und ein ziemlich strenges Limit. Es ist nicht unmöglich, sich zu ändern, aber es gibt einen sehr guten Grund dafür. es zu ändern hat Konsequenzen.

Lassen Sie uns die Wayback-Maschine in die frühen neunziger Jahre zurückversetzen, als Linux entwickelt wurde. Damals hatten wir Streit darüber, ob Linux mit 2 MiB RAM betrieben werden kann oder ob es wirklich 4 ganze MiB benötigt . Natürlich haben uns die High-End-Snobs mit ihren 16-MiB-Monsterservern alle ausgelacht.

Was hat diese amüsante kleine Vignette mit irgendetwas zu tun? In dieser Welt ist es einfach, Entscheidungen darüber zu treffen, wie der 4-GB-Adressraum aufgeteilt werden soll, den Sie durch einfache 32-Bit-Adressierung erhalten. Einige Betriebssysteme teilen es einfach in zwei Hälften auf und behandeln das oberste Bit der Adresse als "Kernel-Flag": Bei den Adressen 0 bis 2 31 -1 wurde das oberste Bit gelöscht und für den Benutzer-Space-Code und die Adressen 2 31 bis 2 32 - Ich hatte das oberste Bit gesetzt und war für den Kernel. Sie können sich einfach die Adresse ansehen und sagen: 0x80000000 und höher, es ist Kernel-Space, ansonsten User-Space.

Als die PC-Speichergröße auf diese 4-GiB-Grenze anstieg, wurde diese einfache 2/2-Aufteilung zum Problem. User Space und Kernel Space hatten beide gute Ansprüche an viel RAM, aber da unser Zweck darin besteht, Benutzerprogramme und nicht Kernel auszuführen, begannen die Betriebssysteme, mit der Trennung von Benutzer und Kernel herumzuspielen. Der 3/1 Split ist ein gängiger Kompromiss.

In Bezug auf Ihre Frage zu physischen vs virtuellen ist es eigentlich egal. Technisch gesehen ist es ein virtuelles Speicherlimit, aber das liegt nur daran, dass Linux ein VM-basiertes Betriebssystem ist. Die Installation von 32 GB physischem RAM ändert nichts und hilft auch nicht bei swaponeiner 32-GB-Swap-Partition. Egal was Sie tun, ein 32-Bit-Linux-Kernel kann niemals mehr als 4 GiB gleichzeitig adressieren.

(Ja, ich weiß über PAE Bescheid . Jetzt, wo 64-Bit-Betriebssysteme endlich die Oberhand gewinnen, hoffe ich, dass wir diesen fiesen Hack vergessen können. Ich glaube nicht, dass es Ihnen in diesem Fall irgendwie helfen kann.)

Die Quintessenz ist, dass Sie den Kernel mit einer 2/2-Aufteilung neu erstellen können, wenn Sie das 1-GiB-Kernel-VM-Limit erreichen. Dies wirkt sich jedoch direkt auf die User-Space-Programme aus.

64-Bit ist wirklich die richtige Antwort.

Warren Young
quelle
1
Vielen Dank. Dieser Artikel ist großartig. Ich habe in den 2/2-Split ausgeführt, der häufig in Windows verwendet wird. Zu dieser Zeit erfuhr ich, dass Linux einen 3/1 Split verwendete. Ich wünschte, ich hätte beim Lesen des Artikels daran gedacht, ich hätte die Punkte verbunden. Also ... das hört sich so an, als müsste ich das im Hinterkopf behalten. Es ist wahrscheinlich nicht weit davon entfernt zu glauben, dass diese Systeme angesichts der Art der Tests an ihre Grenzen stoßen. Die große Frage ist, warum dies nicht auch bei den anderen Systemen der Fall ist. Danke noch einmal.
Andrew Falanga
1
@ AndrewFalanga: Tatsächlich verwendet modernes Windows auch einen Fuzzy-3/1-Split .
Warren Young
1
Einige von uns konnten den Speicher von drei verschiedenen Maschinen, die vom SSC geerbt wurden, kombinieren, um einen 12-MB-Server zu erhalten. So viel Speicher konnten wir tun, was wir wollten ...
dmckee --- Ex-Moderator Kätzchen
3
"Ja, ich kenne das segmentierte x86-Speichermodell . Jetzt, da die 32-Bit-Betriebssysteme endlich die Oberhand gewinnen, hoffe ich, dass wir diesen fiesen Hack vergessen können."
CVn
Es gibt doppelt so viele Verdopplungen zwischen 32- und 64-Bit wie zwischen 16- und 32-Bit, was die Zeit verdoppelt, die wir benötigen, um solche Hacks abzubrechen, wobei alle anderen gleich sind. Aber alles andere ist nicht gleich, wie mit dem Sonnenuntergang von Moores Gesetz. Wir haben zwei Jahrzehnte mit 32-Bit-x86-Computing verbracht. Wir könnten Jahrhunderte aus 64-Bit herausholen. Ein Single-Pass-Lesevorgang von 2⁶⁴ Bytes RAM bei den heutigen DRAM-Bandbreiten würde etwa 30 Jahre dauern . Woher kommt die Erhöhung der Bandbreite, damit wir uns der 64-Bit-Grenze nähern können?
Warren Young
2

Ich möchte ein wenig zu Warren Youngs hervorragender Antwort hinzufügen , weil die Dinge tatsächlich schlimmer sind, als er schreibt.

Der 1-GB-Kernel-Adressraum ist weiter in zwei Teile unterteilt. 128MB sind für vmallocund 896MB für lowmem. Egal was es eigentlich bedeutet. Beim Zuweisen von Speicher muss der Kernel-Code auswählen, welche davon gewünscht werden. Sie können nicht einfach Speicher aus dem Pool abrufen, der über freien Speicherplatz verfügt.

Wenn Sie vmallocmöchten, sind Sie auf 128 MB beschränkt. Jetzt sieht 1GB gar nicht so schlecht aus ...

Wenn Sie lowmemmöchten, sind Sie auf 896 MB beschränkt. Nicht so weit von 1 GB entfernt, aber in diesem Fall werden alle Zuweisungen auf die nächste Potenz von 2 aufgerundet. Eine Zuweisung von 2,3 MB verbraucht also tatsächlich 4 MB. Außerdem können Sie bei Verwendung von nicht mehr als 4 MB in einem Anruf zuweisen lowmem.

64-Bit ist wirklich die richtige Antwort.

ugoren
quelle
Ich habe eine Frage zu Ihrer Antwort. Woher kommt für diesen Speicherbereich mit dem Namen lowmem der Speicher von Aufrufen wie kmalloc und kzmalloc?
Andrew Falanga
@ AndrewFalanga, ja, diese Funktionen verwenden LowMem.
Ugoren