提交 f309db1f 编写于 作者: M Michal Privoznik

qemu: Create memory-backend-{ram,file} iff needed

Libvirt BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1175397
QEMU BZ:    https://bugzilla.redhat.com/show_bug.cgi?id=1170093

In qemu there are two interesting arguments:

1) -numa to create a guest NUMA node
2) -object memory-backend-{ram,file} to tell qemu which memory
region on which host's NUMA node it should allocate the guest
memory from.

Combining these two together we can instruct qemu to create a
guest NUMA node that is tied to a host NUMA node. And it works
just fine. However, depending on machine type used, there might
be some issued during migration when OVMF is enabled (see QEMU
BZ). While this truly is a QEMU bug, we can help avoiding it. The
problem lies within the memory backend objects somewhere. Having
said that, fix on our side consists on putting those objects on
the command line if and only if needed. For instance, while
previously we would construct this (in all ways correct) command
line:

    -object memory-backend-ram,size=256M,id=ram-node0 \
    -numa node,nodeid=0,cpus=0,memdev=ram-node0

now we create just:

    -numa node,nodeid=0,cpus=0,mem=256

because the backend object is obviously not tied to any specific
host NUMA node.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
上级 1adda68a
...@@ -6660,6 +6660,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, ...@@ -6660,6 +6660,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
} }
for (i = 0; i < def->cpu->ncells; i++) { for (i = 0; i < def->cpu->ncells; i++) {
virDomainHugePagePtr hugepage = NULL;
unsigned long long cellmem = VIR_DIV_UP(def->cpu->cells[i].mem, 1024); unsigned long long cellmem = VIR_DIV_UP(def->cpu->cells[i].mem, 1024);
def->cpu->cells[i].mem = cellmem * 1024; def->cpu->cells[i].mem = cellmem * 1024;
virMemAccess memAccess = def->cpu->cells[i].memAccess; virMemAccess memAccess = def->cpu->cells[i].memAccess;
...@@ -6681,7 +6682,6 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, ...@@ -6681,7 +6682,6 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) ||
virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
virDomainNumatuneMemMode mode; virDomainNumatuneMemMode mode;
virDomainHugePagePtr hugepage = NULL;
const char *policy = NULL; const char *policy = NULL;
mode = virDomainNumatuneGetMode(def->numatune, i); mode = virDomainNumatuneGetMode(def->numatune, i);
...@@ -6798,8 +6798,12 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, ...@@ -6798,8 +6798,12 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
virBufferAsprintf(&buf, ",policy=%s", policy); virBufferAsprintf(&buf, ",policy=%s", policy);
} }
virCommandAddArg(cmd, "-object"); if (hugepage || nodemask) {
virCommandAddArgBuffer(cmd, &buf); virCommandAddArg(cmd, "-object");
virCommandAddArgBuffer(cmd, &buf);
} else {
virBufferFreeAndReset(&buf);
}
} else { } else {
if (memAccess) { if (memAccess) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
...@@ -6819,12 +6823,10 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, ...@@ -6819,12 +6823,10 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
virBufferAdd(&buf, tmpmask, -1); virBufferAdd(&buf, tmpmask, -1);
} }
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || if (hugepage || nodemask)
virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) {
virBufferAsprintf(&buf, ",memdev=ram-node%zu", i); virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
} else { else
virBufferAsprintf(&buf, ",mem=%llu", cellmem); virBufferAsprintf(&buf, ",mem=%llu", cellmem);
}
virCommandAddArgBuffer(cmd, &buf); virCommandAddArgBuffer(cmd, &buf);
} }
......
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
/usr/bin/qemu -S -M pc -m 1024 -smp 2 \ /usr/bin/qemu -S -M pc -m 1024 -smp 2 \
-object memory-backend-ram,size=256M,id=ram-node0 \ -numa node,nodeid=0,cpus=0,mem=256 \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-backend-file,prealloc=yes,\ -object memory-backend-file,prealloc=yes,\
mem-path=/dev/hugepages1G/libvirt/qemu,size=768M,id=ram-node1 \ mem-path=/dev/hugepages1G/libvirt/qemu,size=768M,id=ram-node1 \
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ -numa node,nodeid=1,cpus=1,memdev=ram-node1 \
......
...@@ -2,7 +2,6 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ ...@@ -2,7 +2,6 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
/usr/bin/kvm -S -M pc -m 64 -smp 2 \ /usr/bin/kvm -S -M pc -m 64 -smp 2 \
-object memory-backend-ram,size=32M,id=ram-node0,host-nodes=3,policy=preferred \ -object memory-backend-ram,size=32M,id=ram-node0,host-nodes=3,policy=preferred \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ -numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-backend-ram,size=32M,id=ram-node1 \ -numa node,nodeid=1,cpus=1,mem=32 \
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
-nographic -monitor unix:/tmp/test-monitor,server,nowait \ -nographic -monitor unix:/tmp/test-monitor,server,nowait \
-no-acpi -boot c -usb -net none -serial none -parallel none -no-acpi -boot c -usb -net none -serial none -parallel none
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册