I was under the impression that qemu overcommited memory by default, until I ran into good ol':
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
Some straceing later, against a VM with 50G memory assigned, showed that qemu attempts to mmap() the entire guest memory area via:
mmap(0x7ef693e00000, 53687091200, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
Guest memory overcommitting should be as simple as ensuring that MAP_NORESERVE is present in the above flags. Working backwards from qemu_ram_is_noreserve(), the qemu command line parameters to ensure MAP_NORESERVE appear to be:
-object memory-backend-ram,id=pc.ram,size=${mem},reserve=off \
-machine memory-backend=pc.ram \
...instead of the simple -m $mem parameter that we currently use.
I'm not sure of the best way to let rapido use memory overcommit. There are a few options:
- replace the
_rt_qemu_resources_get() -m $mem snippet with the above -object memory-backend-ram...reserve=off parameters.
- leave things as-is and let users manually tweak things via
QEMU_EXTRA_ARGS
- let cut scripts decide whether VM memory should be overcommitted or not via a new helper / cpio flag-file
_rt_mem_overcommit_resources_set, with (1) logic enabled if the overcommit flag is detected.
If overcommit were possible via a simple -overcommit-memory parameter (alongside -m $mem), then I'd definitely opt for (2), but the fact that size=${mem} needs to be present with the -object memory-backend-ram parameter means that VM memory resource requirements specified in the cut script via _rt_mem_resources_set can't easily be considered at boot time.
I really, really, really don't want rapido to go down the path of acting as a map between local configs and qemu cli parameters similar to libvirt. I'm concerned that option (1) leads us further in that direction.
I was under the impression that qemu overcommited memory by default, until I ran into good ol':
Some
straceing later, against a VM with 50G memory assigned, showed that qemu attempts tommap()the entire guest memory area via:Guest memory overcommitting should be as simple as ensuring that
MAP_NORESERVEis present in the above flags. Working backwards fromqemu_ram_is_noreserve(), the qemu command line parameters to ensureMAP_NORESERVEappear to be:...instead of the simple
-m $memparameter that we currently use.I'm not sure of the best way to let rapido use memory overcommit. There are a few options:
_rt_qemu_resources_get() -m $memsnippet with the above-object memory-backend-ram...reserve=offparameters.QEMU_EXTRA_ARGS_rt_mem_overcommit_resources_set, with (1) logic enabled if the overcommit flag is detected.If overcommit were possible via a simple
-overcommit-memoryparameter (alongside-m $mem), then I'd definitely opt for (2), but the fact thatsize=${mem}needs to be present with the-object memory-backend-ramparameter means that VM memory resource requirements specified in the cut script via_rt_mem_resources_setcan't easily be considered at boot time.I really, really, really don't want rapido to go down the path of acting as a map between local configs and qemu cli parameters similar to libvirt. I'm concerned that option (1) leads us further in that direction.