Por que o QEMU não pode alocar a memória se os caches do Linux são muito grandes?

9

Se eu usar minha máquina [Ubuntu 16.04 64 bits, kernel 4.4] por um tempo, o QEMU precisará que os caches do kernel sejam eliminados; caso contrário, ele não conseguirá alocar a RAM.

Por que isso acontece?

Esta é uma amostra de execução:

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        5427        3690          56        5931        4803
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        1799        9446          56        3803        9414
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory

~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          15050        1502       10819          56        2727       10784
Swap:             0           0           0

~$ sudo qemu-system-x86_64 -m 10240 # and other options
# Now QEMU starts
Marcus
fonte
4
Porque você não tem nenhuma troca.
Michael Hampton

Respostas:

19

Nem todos os dados em cache podem ser descartados imediatamente. Por exemplo, as páginas sujas armazenadas em cache precisam ser gravadas de volta no disco antes de poderem ser removidas da RAM. Você não tem troca, portanto, até que essas gravações sejam concluídas, simplesmente não há espaço disponível suficiente para o QEMU.

Você realmente deve adicionar uma quantidade razoável de troca. Você não pode esperar que o gerenciador de memória faça um bom trabalho com uma mão amarrada nas costas.

David Schwartz
fonte
1
Como uma questão teórica (como eu gostaria de aprender mais sobre como o gerenciamento de memória realmente funciona), por que o gerente não pode atrasar (bloquear) as tentativas de alocação de memória do QEMU enquanto as páginas sujas estão sendo gravadas novamente?
Nanofarad
2
@hexafraction Apenas um palpite: provavelmente é tecnicamente possível (mas pode adicionar complexidade significativa, não tenho certeza), mas os desenvolvedores do kernel provavelmente argumentariam que não há necessidade desse recurso, porque o único problema que ele resolve é causado por não ter swap, o que também causa outros problemas, todos corrigidos se você apenas ativar a troca e permitir que o kernel faça seu gerenciamento de memória da maneira que já está codificado para fazer o bem.
Mtraceur # 9/16
1
@hexafraction O kernel não faz ideia de que é uma coisa sensata a se fazer. Para alguns aplicativos, isso não faz sentido, portanto não é a política geral. A QEMU optou por não fazer isso.
David Schwartz
2
@hexafraction Realmente, você gostaria de esperar 30 segundos - ou vários minutos - para sua malloc()chamada para talvez encontrar memória suficiente?
Michael Hampton
3
@hexafraction Pense dessa maneira. Se o kernel tivesse teoricamente esse recurso para bloquear um tempo, caso um malloc falhasse, não haveria maneira de obter o comportamento atual sem APIs adicionais. Por outro lado, a implementação atual permite que o software que deseja aguardar e tentar novamente tente novamente o malloc em um loop lento até que seja satisfeito.
Vality