limite di memoria del kernel Linux


12

Ho un problema imbarazzante. Ho una libreria che utilizza sg per l'esecuzione di CDB personalizzati. Esistono un paio di sistemi che hanno regolarmente problemi con l'allocazione della memoria in sg . Di solito, il driver sg ha un limite massimo di circa 4 MB, ma lo vediamo su questi pochi sistemi con richieste di ~ 2.3 MB. Cioè, i CDB si stanno preparando a stanziare per un trasferimento di 2.3mb. Non ci dovrebbero essere problemi qui: 2.3 <4.0.

Ora, il profilo della macchina. È una CPU a 64 bit ma esegue CentOS 6.0 a 32 bit (non li ho costruiti né ho nulla a che fare con questa decisione). La versione del kernel per questa distribuzione CentOS è 2.6.32. Hanno 16 GB di RAM.

Ecco come appare l'utilizzo della memoria sul sistema (sebbene, poiché questo errore si verifica durante il test automatizzato, non ho ancora verificato se ciò riflette lo stato quando questo errno viene restituito da sg ).

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

Ho trovato questo articolo del Linux Journal che tratta dell'allocazione della memoria nel kernel. L'articolo è datato ma sembra riguardare 2.6 (alcuni commenti sull'autore in testa). L'articolo menziona che il kernel è limitato a circa 1 GB di memoria (anche se non è del tutto chiaro dal testo se quel 1 GB ciascuno per fisico e virtuale o totale). Mi chiedo se questa è un'affermazione accurata per 2.6.32. Alla fine, mi chiedo se questi sistemi stanno raggiungendo questo limite.

Anche se questa non è davvero una risposta al mio problema, mi chiedo della veridicità della richiesta per 2.6.32. Quindi, qual è il limite effettivo di memoria per il kernel? Potrebbe essere necessario prendere in considerazione la risoluzione dei problemi. Qualsiasi altro suggerimento è il benvenuto. Ciò che rende questo così sconcertante è che questi sistemi sono identici a molti altri che non mostrano questo stesso problema.

Risposte:


21

Il limite di 1 GiB per la memoria del kernel Linux in un sistema a 32 bit è una conseguenza dell'indirizzamento a 32 bit ed è un limite piuttosto rigido. Non è impossibile cambiare, ma è lì per un'ottima ragione; cambiarlo ha conseguenze.

Prendiamo la macchina del ritorno ai primi anni '90, quando è stato creato Linux. A quei tempi, avremmo avuto delle discussioni sul fatto che Linux potesse essere fatto funzionare con 2 MiB di RAM o se avesse davvero bisogno di 4 MiB interi . Ovviamente, gli snob di fascia alta ci stavano tutti deridendo, con i loro 16 monster server MiB.

Cosa c'entra quella piccola vignetta divertente con qualcosa? In quel mondo, è facile prendere decisioni su come dividere lo spazio degli indirizzi di 4 GiB che si ottiene dal semplice indirizzamento a 32 bit. Alcuni sistemi operativi lo hanno appena diviso a metà, trattando il bit superiore dell'indirizzo come "flag del kernel": gli indirizzi da 0 a 2 31 -1 hanno il bit superiore cancellato, e sono stati per il codice dello spazio utente e gli indirizzi da 2 31 a 2 32 - 1 aveva il bit più alto impostato ed era per il kernel. Potresti semplicemente guardare l'indirizzo e dire: 0x80000000 e successivi, è spazio kernel, altrimenti è spazio utente.

Man mano che le dimensioni della memoria del PC aumentavano rapidamente fino a quel limite di memoria di 4 GiB, questa semplice divisione 2/2 ha iniziato a diventare un problema. Lo spazio utente e lo spazio del kernel avevano entrambi buone pretese su molta RAM, ma poiché il nostro scopo nell'avere un computer è generalmente quello di eseguire programmi utente, piuttosto che eseguire kernel, i sistemi operativi hanno iniziato a giocare con il divario utente / kernel. La divisione 3/1 è un compromesso comune.

Per quanto riguarda la tua domanda su fisico vs virtuale, in realtà non importa. Tecnicamente parlando, è un limite di memoria virtuale, ma è solo perché Linux è un sistema operativo basato su VM. L'installazione di 32 GiB di RAM fisica non cambierà nulla, né aiuterà a swaponuna partizione di swap da 32 GiB. Indipendentemente da ciò che fai, un kernel Linux a 32 bit non sarà mai in grado di indirizzare più di 4 GiB contemporaneamente.

(Sì, lo so di PAE . Ora che i sistemi operativi a 64 bit stanno finalmente prendendo il sopravvento, spero che possiamo iniziare a dimenticare quel brutto hack. Non credo che possa aiutarti in questo caso comunque.)

La linea di fondo è che se si esegue il limite VM del kernel 1 GiB, è possibile ricostruire il kernel con una suddivisione 2/2, ma ciò ha un impatto diretto sui programmi di spazio utente.

64 bit è davvero la risposta giusta.


1
Grazie. Questo commento è fantastico. Ho incontrato la divisione 2/2 comunemente usata in Windows. A quel tempo, ho imparato che Linux utilizzava una divisione 3/1. Avrei voluto pensarci mentre leggevo l'articolo, penso che avrei collegato i punti. Quindi ... sembra che dovrò tenerlo a mente. Probabilmente non è fuori portata pensare che questi sistemi stiano raggiungendo i limiti considerando la natura dei test. La grande domanda è: perché non stanno vivendo anche gli altri sistemi. Grazie ancora.
Andrew Falanga,

1
@AndrewFalanga: In realtà, anche Windows moderno utilizza una suddivisione fuzzy 3/1 .
Warren Young,

1
Alcuni di noi sono stati in grado di combinare la memoria di tre diverse macchine ereditate dall'SSC per ottenere un server da 12 MB. Così tanta memoria che potremmo fare tutto ciò che volevamo ...
dmckee --- ex gattino moderatore

3
"Sì, conosco il modello di memoria segmentata x86 . Ora che i sistemi operativi a 32 bit stanno finalmente prendendo il sopravvento, spero che possiamo iniziare a dimenticare quel brutto hack."
un CVn

Ci sono il doppio dei duplicati tra 32 e 64 bit tra 16 e 32, il che raddoppia il tempo che dobbiamo rimandare a tali hack, a parità di tutti gli altri. Ma tutto il resto non è uguale, per quanto riguarda il tramonto della Legge di Moore. Abbiamo ottenuto due decenni di elaborazione x86 a 32 bit. Potremmo ottenere secoli da 64 bit. Una lettura single-pass di 2⁶⁴ byte di RAM alle larghezze di banda DRAM odierne richiederebbe circa 30 anni . Da dove verrà l'aumento della larghezza di banda per consentirci di avvicinarci al limite a 64 bit?
Warren Young,

2

Voglio aggiungere un po 'all'ottima risposta di Warren Young , perché le cose sono effettivamente peggiori di quanto scriva.

Lo spazio degli indirizzi del kernel da 1 GB è ulteriormente suddiviso in due parti. 128 MB sono per vmalloce 896 MB per lowmem. Non importa cosa significhi effettivamente. Quando si alloca memoria, il codice del kernel deve scegliere quale di questi desidera. Non puoi semplicemente ottenere memoria da qualsiasi pool abbia spazio libero.

Se lo desideri vmalloc, hai un limite di 128 MB. Ora 1 GB non sembra così male ...

Se lo desideri lowmem, hai un limite di 896 MB. Non così lontano da 1 GB, ma in questo caso, tutte le allocazioni sono arrotondate alla potenza successiva di 2. Quindi un'allocazione di 2,3 MB consuma effettivamente 4 MB. Inoltre, non è possibile allocare più di 4 MB in una chiamata durante l'utilizzo lowmem.

64 bit è davvero la risposta giusta.


Ho una domanda relativa alla tua risposta. Per questo spazio di memoria chiamato lowmem , è da dove viene la memoria di chiamate come kmalloc e kzmalloc?
Andrew Falanga,

@AndrewFalanga, sì, queste funzioni usano lowmem.
ugoren,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.