límite de memoria del kernel de Linux

12

Tengo un problema desconcertante. Tengo una biblioteca que usa sg para ejecutar CDB personalizados. Hay un par de sistemas que habitualmente tienen problemas con la asignación de memoria en sg . Por lo general, el controlador sg tiene un límite estricto de alrededor de 4 mb, pero lo vemos en estos pocos sistemas con ~ 2.3 mb de solicitudes. Es decir, los CDB se están preparando para asignar una transferencia de 2.3mb. No debería haber ningún problema aquí: 2.3 <4.0.

Ahora, el perfil de la máquina. Es una CPU de 64 bits pero ejecuta CentOS 6.0 de 32 bits (no los construí ni tengo nada que ver con esta decisión). La versión del kernel para esta distribución CentOS es 2.6.32. Tienen 16 gb de RAM.

Así es como se ve el uso de la memoria en el sistema (sin embargo, debido a que este error ocurre durante las pruebas automatizadas, aún no he verificado si esto refleja el estado en el que se devuelve este error de 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

Encontré este artículo de Linux Journal que trata sobre la asignación de memoria en el núcleo. El artículo está fechado pero parece pertenecer a 2.6 (algunos comentarios sobre el autor a la cabeza). El artículo menciona que el núcleo está limitado a aproximadamente 1 gb de memoria (aunque no está completamente claro en el texto si ese 1 gb es físico, virtual o total). Me pregunto si esta es una declaración precisa para 2.6.32. En última instancia, me pregunto si estos sistemas están alcanzando este límite.

Aunque esto no es realmente una respuesta a mi problema, me pregunto sobre la veracidad del reclamo de 2.6.32. Entonces, ¿cuál es el límite real de memoria para el núcleo? Es posible que esto deba considerarse para la resolución de problemas. Cualquier otra sugerencia es bienvenida. Lo que hace que esto sea tan desconcertante es que estos sistemas son idénticos a muchos otros que no muestran este mismo problema.

Andrew Falanga
fuente

Respuestas:

21

El límite de 1 GiB para la memoria del núcleo Linux en un sistema de 32 bits es una consecuencia del direccionamiento de 32 bits, y es un límite bastante rígido. No es imposible cambiar, pero está ahí por una muy buena razón; cambiarlo tiene consecuencias.

Llevemos la máquina del camino a principios de la década de 1990, cuando se estaba creando Linux. En aquellos días, tendríamos argumentos sobre si Linux podría ejecutarse en 2 MiB de RAM o si realmente necesitaba 4 MiB completos . Por supuesto, los esnobs de alta gama se burlaban de nosotros, con sus 16 servidores monstruos MiB.

¿Qué tiene que ver esa pequeña viñeta divertida con algo? En ese mundo, es fácil tomar decisiones sobre cómo dividir el espacio de direcciones de 4 GiB que obtiene de un simple direccionamiento de 32 bits. Algunos sistemas operativos simplemente lo dividen por la mitad, tratando el bit superior de la dirección como el "indicador del núcleo": las direcciones 0 a 2 31 -1 tenían el bit superior borrado, y eran para el código de espacio del usuario, y las direcciones 2 31 a 2 32 - 1 tenía el bit superior establecido y eran para el núcleo. Podrías mirar la dirección y decir: 0x80000000 y más, es espacio de kernel, de lo contrario es espacio de usuario.

A medida que los tamaños de memoria de la PC se dispararon hacia ese límite de memoria de 4 GiB, esta división simple de 2/2 comenzó a convertirse en un problema. El espacio del usuario y el espacio del kernel tenían buenos reclamos sobre la gran cantidad de RAM, pero dado que nuestro propósito en tener una computadora es generalmente ejecutar programas de usuario, en lugar de ejecutar kernels, los sistemas operativos comenzaron a jugar con la división usuario / kernel. La división 3/1 es un compromiso común.

En cuanto a su pregunta sobre físico vs virtual, en realidad no importa. Técnicamente hablando, es un límite de memoria virtual, pero eso es solo porque Linux es un sistema operativo basado en VM. La instalación de 32 GiB de RAM física no cambiará nada, ni ayudará a swaponuna partición de intercambio de 32 GiB. No importa lo que haga, un kernel de Linux de 32 bits nunca podrá direccionar más de 4 GiB simultáneamente.

(Sí, sé sobre PAE . Ahora que los sistemas operativos de 64 bits finalmente se están haciendo cargo, espero que podamos comenzar a olvidar ese truco desagradable. No creo que pueda ayudarlo en este caso de todos modos).

La conclusión es que si se encuentra con el límite de VM del núcleo de 1 GiB, puede reconstruir el núcleo con una división de 2/2, pero eso afecta directamente a los programas de espacio de usuario.

64 bits realmente es la respuesta correcta.

Warren Young
fuente
1
Gracias. Este artículo es genial. Me he encontrado con la división 2/2 comúnmente utilizada en Windows. En ese momento, aprendí que Linux usaba una división 3/1. Desearía haber pensado en eso al leer el artículo, creo que habría conectado los puntos. Entonces ... parece que tendré que tener esto en cuenta. Probablemente no esté fuera de alcance pensar que estos sistemas están llegando a los límites considerando la naturaleza de las pruebas. La gran pregunta es, ¿por qué los otros sistemas no están experimentando esto también? Gracias de nuevo.
Andrew Falanga el
1
@AndrewFalanga: En realidad, Windows moderno también usa una división difusa de 3/1 .
Warren Young el
1
Algunos de nosotros pudimos combinar la memoria de tres máquinas diferentes heredadas del SSC para obtener un servidor de 12 MB. Por lo tanto la memoria que podíamos hacer lo que quisiéramos ...
dmckee --- ex-moderador gatito
3
"Sí, sé sobre el modelo de memoria segmentada x86 . Ahora que los sistemas operativos de 32 bits finalmente se están haciendo cargo, espero que podamos comenzar a olvidar ese truco desagradable".
un CVn
Hay el doble de duplicaciones entre 32 y 64 bits que entre 16 y 32, lo que duplica la cantidad de tiempo que tenemos para aplazar tales ataques, todo lo demás es igual. Pero todo lo demás no es igual, con la puesta de sol de la Ley de Moore. Obtuvimos dos décadas de la computación x86 de 32 bits. Podríamos sacar siglos de 64 bits. Una lectura de un solo paso de 2⁶⁴ bytes de RAM en los anchos de banda DRAM actuales tomaría aproximadamente 30 años . ¿De dónde vendrá el aumento del ancho de banda para permitirnos acercarnos al límite de 64 bits?
Warren Young
2

Quiero agregar un poco a la excelente respuesta de Warren Young , porque las cosas son realmente peores de lo que escribe.

El espacio de direcciones del núcleo de 1 GB se divide en dos partes. 128 MB son para vmallocy 896 MB para lowmem. No importa lo que realmente signifique. Al asignar memoria, el código del núcleo debe elegir cuál de estos quiere. No puede obtener memoria de la agrupación que tenga espacio libre.

Si elige vmalloc, tiene un límite de 128 MB. Ahora 1GB no se ve tan mal ...

Si elige lowmem, tiene un límite de 896 MB. No muy lejos de 1 GB, pero en este caso, todas las asignaciones se redondean a la siguiente potencia de 2. Por lo tanto, una asignación de 2,3 MB realmente consume 4 MB. Además, no puede asignar más de 4 MB en una llamada cuando se usa lowmem.

64 bits realmente es la respuesta correcta.

Ugoren
fuente
Tengo una pregunta relacionada con tu respuesta. Para este espacio de memoria llamado lowmem , ¿es de aquí de donde provienen la memoria de llamadas como kmalloc y kzmalloc?
Andrew Falanga
@ AndrewFalanga, sí, estas funciones usan lowmem.
ugoren