Comportamento estranho com cache Unevictable (kernel Linux)

Comportamento estranho com cache Unevictable (kernel Linux)

Estou vendo um comportamento que não consigo explicar no meu destino Linux incorporado (initramfs esem troca).

Como não há troca, eu esperaria que qualquer coisa em /tmp (tmpfs) fosse sinalizada como inviável. Em vez disso, estou observando o seguinte ao usar o seguinte 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
  • Se gravar muitos arquivos de 10 MB, o Shmem cresce linearmente, mas a memória inevitável salta de 0 KB para ~ 200 MB muito rapidamente:

    #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
    
  • Se eu excluir todos os arquivos zero, a memória inviável permanecerá no mesmo nível. Isso significa que perdi toda aquela RAM? Parece que o assassino OOM parece ter sido invocado anteriormente. Como posso recuperá-lo?

    # rm /tmp/zero*
    # cat /proc/meminfo | grep 'Unevictable\|Shmem'
    Unevictable:      288372 kB
    Shmem:             48412 kB
    
  • Com pedaços de 100 MB em vez 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
    

Alguém pode explicar o comportamento observado, que me parece um bug do Kernel.

Obrigado

Responder1

Suspeito que não seja um tmpfs - mas um ramfs.

A lista não-removível aborda as seguintes classes de páginas não-removíveis:

  • Aqueles pertencentes a ramfs.

  • Aqueles mapeados em SHM_LOCKregiões de memória compartilhada.

  • Aqueles mapeados em VM_LOCKEDVMAs [mlock()ed].

A infra-estrutura também poderá ser capaz de lidar com outras condições que tornem as páginas inviáveis, seja por definição ou por circunstância, no futuro.

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

Em resposta a sua pergunta,Chapéu vermelhoresumir "Inevitável" como "A quantidade de memória, em kibibytes,descoberto pelo código pageout, isso não pode ser removido porque está bloqueado na memória pelos programas do usuário."

Lendo o documento completo, parece que, por algum motivo, ramfsas alocações começam na Inactive(anon)lista LRU normal. Depois que você ficar sem memória livre e começar a acionar a recuperação (pageout), as listas serão verificadas e a VM "descobrirá" a memória bloqueada e a moverá para a lista não-removível.

Numa nota relacionada, há também umacomentário do kernelo que sugere que o campo "Mlocked" pode não contabilizar páginas bloqueadas imediatamente. (Talvez aconteça em alguns casos, não verifiquei).

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

Não estou assumindo que o kernel varre a lista inteira de uma vez, mas espero que ele a varra em grandes lotes.

O problema com esta teoria é que não sei por que/como seu kernel verificaria as listas "anon", se você não tiver nenhuma troca configurada. Eu até encontrei ocó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;
}

informação relacionada