Dlaczego QEMU nie może przydzielić pamięci, jeśli pamięci podręczne systemu Linux są zbyt duże?

9

Jeśli korzystam z mojego komputera [Ubuntu 16.04 64 bit, jądro 4.4], QEMU potrzebuje pamięci podręcznej jądra, aby zostać upuszczonym, w przeciwnym razie nie uda mu się przydzielić pamięci RAM.

Dlaczego tak się dzieje?

To jest przykładowy przebieg:

~$ 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
źródło
4
Ponieważ nie masz zamiany.
Michael Hampton,

Odpowiedzi:

19

Nie wszystkie buforowane dane można natychmiast usunąć. Na przykład buforowane brudne strony muszą zostać zapisane z powrotem na dysk, zanim można je usunąć z pamięci RAM. Nie masz zamiany, więc dopóki zapisy nie zostaną ukończone, po prostu nie ma wystarczającej ilości miejsca dla QEMU.

Naprawdę powinieneś dodać rozsądną ilość zamiany. Nie można oczekiwać, że menedżer pamięci wykona dobrą robotę, trzymając jedną rękę za plecami.

David Schwartz
źródło
1
Jako teoretyczne pytanie (skoro chciałbym dowiedzieć się więcej o tym, jak faktycznie działa zarządzanie pamięcią), dlaczego menedżer nie może opóźnić (zablokować) prób alokacji pamięci przez QEMU podczas zapisywania brudnych stron?
nanofarad
2
@ hexafraction Tylko zgadnij: jest to prawdopodobnie technicznie możliwe (ale może dodać znaczną złożoność, nie jestem pewien), ale deweloperzy jądra prawdopodobnie twierdzą, że nie jest potrzebna ta funkcja, ponieważ jedynym problemem, który rozwiązuje, jest brak wymiany, która powoduje również inne problemy, z których wszystkie zostaną naprawione, jeśli po prostu włączysz swap i pozwolisz jądru zarządzać pamięcią w sposób, w jaki jest już dobrze zakodowany.
mtraceur
1
@hexafraction Jądro nie ma pojęcia, że ​​jest to rozsądne. W przypadku niektórych aplikacji nie ma to sensu, więc nie jest to ogólna zasada. QEMU zdecydowało się tego nie robić.
David Schwartz,
2
@hexafraction Naprawdę, co chcesz czekać 30 sekund - lub kilka minut - za malloc()wywołanie może znaleźć wystarczającej ilości pamięci?
Michael Hampton,
3
@hexafraction Pomyśl o tym w ten sposób. Gdyby jądro teoretycznie miało tę funkcję do zablokowania na chwilę, gdyby malloc w innym przypadku zawiodłby, nie byłoby sposobu na osiągnięcie obecnego zachowania bez dodatkowych API. Z drugiej strony, obecna implementacja pozwala oprogramowaniu, które chce poczekać i ponowić próbę, aby ponowić próbę malloc w wolnej pętli, dopóki nie zostanie spełniona.
Vality,