2008-09-22 14 views
91

Busqué en Google y descubrí que la mayoría de las personas abogan por el uso de kmalloc, ya que se garantiza que obtendrá bloques físicos contiguos de memoria. Sin embargo, también parece que kmalloc puede fallar si no se encuentra un bloque contiguo físico que desee.
¿Cuáles son las ventajas de tener un bloque de memoria contiguo? En concreto, ¿por qué necesitaría tener una contigua física bloque de memoria en una llamada de sistema ? ¿Hay alguna razón por la que no pueda usar vmalloc?
Finalmente, si tuviera que asignar memoria durante el manejo de una llamada al sistema, ¿debería especificar GFP_ATOMIC? ¿Se ejecuta una llamada al sistema en un contexto atómico?¿Cuál es la diferencia entre vmalloc y kmalloc?

GFP_ATOMIC
La asignación es de alta prioridad y no duerme. Esta es la bandera de uso en el manejador de interrupciones, de fondo mitades y otras situaciones en las que no puede dormir.

GFP_KERNEL Esta es una asignación normal y podría bloquear. Esta es la bandera para usar en el código de contexto del proceso cuando es seguro dormir.

+0

Un buen artículo sobre vmalloc y kmalloc [http://learnlinuxconcepts.blogspot.in/2014/02/linux-memory-management.html](http://learnlinuxconcepts.blogspot.in/2014/02/linux- memory-management.html) – JIN007

Respuesta

76

sólo tendrá que preocuparse sobre el uso de memoria físicamente contigua si el búfer se accede por un dispositivo DMA en un autobús física dirigida (como PCI). El problema es que muchas llamadas al sistema no tienen forma de saber si su búfer finalmente se pasará a un dispositivo DMA: una vez que pasa el búfer a otro subsistema del kernel, realmente no puede saber a dónde irá. Incluso si el kernel no utiliza el búfer para DMA hoy, un futuro desarrollo podría hacerlo.

vmalloc es a menudo más lento que kmalloc, porque puede tener que reasignar el espacio del búfer en un rango virtualmente contiguo. kmalloc nunca reasigna, aunque si no se llama con GFP_ATOMIC puede bloquear kmalloc.

kmalloc está limitada en el tamaño de memoria intermedia que puede proporcionar: 128 KBytes *). Si necesita un búfer realmente grande, debe usar vmalloc u otro mecanismo como reservar memoria alta en el arranque.

*)Este fue el caso de los núcleos anteriores. En núcleos recientes (¡lo probé en 2.6.33.2), el tamaño máximo de un solo kmalloc es de hasta 4 MB! (Escribí bastante detailed post on this.) — Kaiwan

Para una llamada de sistema que no es necesario pasar a GFP_ATOMIC kmalloc(), puede utilizar GFP_KERNEL. No es un controlador de interrupciones: el código de la aplicación ingresa al contexto del kernel por medio de una trampa, no es una interrupción.

+1

Pensé que las llamadas al sistema se ingresaron activando int $ 0x80? (es decir, una interrupción)? – FreeMemory

+2

int $ 0x80 es una interrupción de software, también llamada trampa. Lo que se entiende por manejadores de interrupciones es una interrupción de hardware, como cuando el usuario presiona una tecla o mueve los movimientos. – Branan

+0

Las llamadas al sistema son para el espacio de usuario para las transiciones del espacio del kernel ... ¿kmalloc se usa solo en el contexto del kernel? – AIB

6

¿Cuáles son las ventajas de tener un bloque de memoria contiguo? Específicamente, ¿por qué necesitaría tener un bloque físico contiguo de memoria en una llamada al sistema? ¿Hay alguna razón por la que no pueda usar vmalloc?

De "Voy a tener suerte" de Google en vmalloc:

kmalloc es la manera preferida, siempre y cuando no se necesita áreas muy grandes. El problema es que si quieres hacer DMA desde/hacia algún dispositivo de hardware, necesitarás usar kmalloc, y probablemente necesites un pedazo más grande. La solución es asignar memoria lo antes posible, antes de que la memoria se fragmente.

+0

Mira, lo leí y no tiene sentido para mí. Entiendo usar kmalloc para las áreas __big__; pero para pequeñas asignaciones, ¿por qué no utilizar vmalloc para evitar la fragmentación de la memoria física? – FreeMemory

+0

Porque debes confiar en el kernel para hacer lo mejor; si piensa que asignar un solo trozo es mejor, lo hará. vmalloc es solo para cuando absolutamente * debes * tener un fragmento contiguo. –

+0

Supongo que tiene sentido, pero parece contradictorio. kmalloc suena como debería ser usado cuando el rendimiento es de gran preocupación (es decir, no puedo estar plagado de disco IO). Además, ¿qué pasa con GFP_ATOMIC? – FreeMemory

16

Respuesta corta: Linux Device Drivers descargar y leer el capítulo sobre la gestión de memoria.

En serio, hay un montón de cuestiones sutiles relacionadas con la gestión de memoria del kernel que es necesario entender - Paso mucho de mis problemas de depuración de tiempo con ella.

vmalloc() se utiliza muy raramente, debido a que el núcleo raramente utiliza memoria virtual. kmalloc() es lo que normalmente se usa, pero debes saber cuáles son las consecuencias de las diferentes banderas y necesitas una estrategia para lidiar con lo que sucede cuando falla, especialmente si estás en un manejador de interrupciones, como sugeriste.

+0

"porque el kernel rara vez usa memoria virtual", ¿por qué? – Trey

1

Una de las otras diferencias es que kmalloc devolverá la dirección lógica (si no especifica GPF_HIGHMEM). Las direcciones lógicas se colocan en "memoria baja" (en el primer gigabyte de memoria física) y se asignan directamente a direcciones físicas (use __pa macro para convertirlo). Esta propiedad implica que la memoria kmalloced es memoria continua.

Por otro lado, Vmalloc puede devolver direcciones virtuales desde "memoria alta". Estas direcciones no se pueden convertir en direcciones físicas de forma directa (debe usar la función virt_to_page).

9

Linux Kernel Development por Robert Love (Capítulo 12, página 244 en 3ra edición) responde esto muy claramente.

Sí, la memoria físicamente contigua no es necesaria en muchos de los casos. La razón principal para usar kmalloc más que vmalloc en kernel es el rendimiento. El libro explica, cuando los trozos de memoria grandes se asignan usando vmalloc, kernel tiene que mapear los fragmentos (páginas) físicamente no contiguos en una sola región de memoria virtual contigua. Como la memoria es virtualmente contigua y físicamente no contigua, varias asignaciones de direcciones virtuales a físicas deberán agregarse a la tabla de páginas. Y en el peor de los casos, habrá (tamaño del búfer/tamaño de página) número de asignaciones agregadas a la tabla de páginas.

Esto también agrega presión sobre TLB (las entradas de caché que almacenan asignaciones de direcciones virtuales a físicas recientes) al acceder a este búfer. Esto puede llevar al thrashing.

7

kmalloc() & vmalloc() funciones son una interfaz simple para obtener la memoria del kernel en trozos de tamaño byte.

  1. La función kmalloc() garantiza que las páginas son físicamente contigua (y prácticamente contiguo).

  2. La función vmalloc() funciona de manera similar a kmalloc(), excepto que asigna memoria que es solo virtualmente contigua y no necesariamente contigua físicamente.

1

En un sistema de 32 bits, kmalloc() devuelve la dirección lógica del núcleo (su una dirección virtual aunque) que tiene la asignación directa (en realidad con desplazamiento constante) a la dirección física. Este mapeo directo garantiza que obtengamos un fragmento físico contiguo de RAM. Adecuado para DMA donde damos solo el puntero inicial y esperamos un mapeo físico contiguo para nuestra operación.

vmalloc() devuelve la dirección virtual del kernel que a su vez puede no estar teniendo una asignación contigua en la RAM física. Útil para la asignación de memoria grande y en los casos en que no nos importa que la memoria asignada a nuestro proceso sea continua también en la RAM física.

Cuestiones relacionadas