Comportamiento extraño con caché Unevictable (kernel de Linux)

Comportamiento extraño con caché Unevictable (kernel de Linux)

Veo un comportamiento que no puedo explicar en mi destino Linux integrado (initramfs ysin intercambio).

Como no hay intercambio, esperaría que cualquier cosa en /tmp (tmpfs) se marque como no desalojable. En cambio, observo lo siguiente cuando uso el siguiente script:

#!/bin/sh
count=1
while true; do
    echo "#$count"
    dd if=/dev/zero of=/tmp/zero$count bs=1M count=10 && cat /proc/meminfo | grep 'Unevictable\|Shmem'
    count=`expr $count + 1`
    sleep 3
done
  • Si se escriben muchos archivos de 10 MB, Shmem crece linealmente pero la memoria inevitable salta de 0 KB a ~200 MB muy rápidamente:

    #40
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.102484 seconds, 97.6MB/s
    Unevictable:           0 kB
    Shmem:            453776 kB
    #41
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.047640 seconds, 209.9MB/s
    Unevictable:           0 kB
    Shmem:            464196 kB
    #42
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.101833 seconds, 98.2MB/s
    Unevictable:         884 kB
    Shmem:            474616 kB
    #43
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.051686 seconds, 193.5MB/s
    Unevictable:      234612 kB
    Shmem:            485040 kB
    #44
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.052157 seconds, 191.7MB/s
    Unevictable:      238568 kB
    Shmem:            495572 kB
    #45
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.043332 seconds, 230.8MB/s
    Unevictable:      245332 kB
    Shmem:            505892 kB
    #46
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.042653 seconds, 234.4MB/s
    Unevictable:      245332 kB
    Shmem:            516312 kB
    #47
    10+0 records in
    10+0 records out
    10485760 bytes (10.0MB) copied, 0.048478 seconds, 206.3MB/s
    Unevictable:      248384 kB
    Shmem:            526724 kB
    
  • Si elimino todos los archivos cero, la memoria que no se puede desalojar permanece en el mismo nivel. ¿Significa que perdí toda esa RAM? Parece que el asesino OOM parece haber sido invocado antes. ¿Cómo puedo reclamarlo?

    # rm /tmp/zero*
    # cat /proc/meminfo | grep 'Unevictable\|Shmem'
    Unevictable:      288372 kB
    Shmem:             48412 kB
    
  • Con fragmentos de 100 MB en lugar de 10 MB:

    #1
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.422820 seconds, 236.5MB/s
    Unevictable:           0 kB
    Shmem:            150168 kB
    #2
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.471385 seconds, 212.1MB/s
    Unevictable:           0 kB
    Shmem:            252516 kB
    #3
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.444059 seconds, 225.2MB/s
    Unevictable:           0 kB
    Shmem:            354888 kB
    #4
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 0.414981 seconds, 241.0MB/s
    Unevictable:           0 kB
    Shmem:            457368 kB
    #5
    100+0 records in
    100+0 records out
    104857600 bytes (100.0MB) copied, 5.538392 seconds, 18.1MB/s
    Unevictable:      288264 kB
    Shmem:            559700 kB
    #6
    dd: writing '/tmp/zero6': No space left on device
    

¿Alguien puede explicar el comportamiento observado, que me parece un error del Kernel?

Gracias

Respuesta1

Sospecho que no es un tmpfs, sino un ramfs.

La lista no desalojable aborda las siguientes clases de páginas no desalojables:

  • Los propiedad de ramfs.

  • Aquellos asignados a SHM_LOCKregiones de memoria compartida.

  • Aquellos asignados a VM_LOCKEDVMA [mlock()ed].

La infraestructura también puede ser capaz de manejar otras condiciones que hagan que las páginas no puedan ser desalojadas, ya sea por definición o por circunstancias, en el futuro.

https://www.kernel.org/doc/Documentation/vm/unevictable-lru.txt

En respuesta a tu pregunta,Sombrero rojoresumir "inevictable" como "La cantidad de memoria, en kibibytes,descubierto por el código de salida de página, que no se puede desalojar porque está bloqueado en la memoria por los programas del usuario".

Al leer el documento completo, parece que, por alguna razón, ramfslas asignaciones comienzan en la Inactive(anon)lista LRU normal. Una vez que se queda sin memoria libre y comienza a activar la recuperación (salida de página), las listas se escanean y la VM "descubrirá" la memoria bloqueada y la moverá a la lista que no se puede desalojar.

En una nota relacionada, también hay unacomentario del núcleolo que sugiere que es posible que el campo "Mlocked" no tenga en cuenta las páginas bloqueadas de inmediato. (Tal vez sea así en algunos casos, no lo he comprobado).

NR_MLOCK,       /* mlock()ed pages found and moved off LRU */

No estoy asumiendo que el kernel escanea toda la lista a la vez, pero espero que la analice en lotes grandes.

El problema con esta teoría es que no sé por qué/cómo su núcleo escanearía las listas "anónimas", si no tiene ningún intercambio configurado. Incluso encontré elcódigo-

/* If we have no swap space, do not bother scanning anon pages. */
if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) {
    scan_balance = SCAN_FILE;
    goto out;
}

información relacionada