提交 1c19d3e0 编写于 作者: M Martin Kletzander

qemu: pass numa node binding preferences to qemu

Currently, we only bind the whole QEMU domain to memory nodes
specified in nodemask altogether.  That, however, doesn't make much
sense when one wants to control from where the memory for particular
guest nodes should be allocated.  QEMU allows us to do that by
specifying 'host-nodes' parameter for the 'memory-backend-ram' object,
so let's use that.
Signed-off-by: NMartin Kletzander <mkletzan@redhat.com>
上级 001b9dc1
......@@ -150,6 +150,11 @@ VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST,
NULL,
NULL);
VIR_ENUM_DECL(qemuNumaPolicy)
VIR_ENUM_IMPL(qemuNumaPolicy, VIR_DOMAIN_NUMATUNE_MEM_LAST,
"bind",
"preferred",
"interleave");
/**
* qemuPhysIfaceConnect:
......@@ -6383,13 +6388,23 @@ qemuBuildNumaArgStr(const virDomainDef *def,
size_t i;
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *cpumask = NULL, *tmpmask = NULL, *next = NULL;
char *nodemask = NULL;
int ret = -1;
if (virDomainNumatuneHasPerNodeBinding(def->numatune) &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Per-node memory binding is not supported "
"with this QEMU"));
goto cleanup;
}
for (i = 0; i < def->cpu->ncells; i++) {
int cellmem = VIR_DIV_UP(def->cpu->cells[i].mem, 1024);
def->cpu->cells[i].mem = cellmem * 1024;
VIR_FREE(cpumask);
VIR_FREE(nodemask);
if (!(cpumask = virBitmapFormat(def->cpu->cells[i].cpumask)))
goto cleanup;
......@@ -6402,6 +6417,43 @@ qemuBuildNumaArgStr(const virDomainDef *def,
goto cleanup;
}
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) {
virDomainNumatuneMemMode mode;
const char *policy = NULL;
mode = virDomainNumatuneGetMode(def->numatune, i);
policy = qemuNumaPolicyTypeToString(mode);
virBufferAsprintf(&buf, "memory-backend-ram,size=%dM,id=ram-node%zu",
cellmem, i);
if (virDomainNumatuneMaybeFormatNodeset(def->numatune, NULL,
&nodemask, i) < 0)
goto cleanup;
if (nodemask) {
if (strchr(nodemask, ',') &&
!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("disjoint NUMA node ranges are not supported "
"with this QEMU"));
goto cleanup;
}
for (tmpmask = nodemask; tmpmask; tmpmask = next) {
if ((next = strchr(tmpmask, ',')))
*(next++) = '\0';
virBufferAddLit(&buf, ",host-nodes=");
virBufferAdd(&buf, tmpmask, -1);
}
virBufferAsprintf(&buf, ",policy=%s", policy);
}
virCommandAddArg(cmd, "-object");
virCommandAddArgBuffer(cmd, &buf);
}
virCommandAddArg(cmd, "-numa");
virBufferAsprintf(&buf, "node,nodeid=%zu", i);
......@@ -6412,7 +6464,11 @@ qemuBuildNumaArgStr(const virDomainDef *def,
virBufferAdd(&buf, tmpmask, -1);
}
virBufferAsprintf(&buf, ",mem=%d", cellmem);
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) {
virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
} else {
virBufferAsprintf(&buf, ",mem=%d", cellmem);
}
virCommandAddArgBuffer(cmd, &buf);
}
......@@ -6420,6 +6476,7 @@ qemuBuildNumaArgStr(const virDomainDef *def,
cleanup:
VIR_FREE(cpumask);
VIR_FREE(nodemask);
virBufferFreeAndReset(&buf);
return ret;
}
......
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 \
-object memory-backend-ram,size=32M,id=ram-node0,host-nodes=3,policy=preferred \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-backend-ram,size=32M,id=ram-node1 \
-numa node,nodeid=1,cpus=1,memdev=ram-node1 \
-nographic -monitor unix:/tmp/test-monitor,server,nowait \
-no-acpi -boot c -usb -net none -serial none -parallel none
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
/usr/bin/kvm -S -M pc -m 24104 -smp 32 \
-object memory-backend-ram,size=20M,id=ram-node0,host-nodes=3,policy=preferred \
-numa node,nodeid=0,cpus=0,memdev=ram-node0 \
-object memory-backend-ram,size=645M,id=ram-node1,host-nodes=0-7,policy=bind \
-numa node,nodeid=1,cpus=1-27,cpus=29,memdev=ram-node1 \
-object memory-backend-ram,size=23440M,id=ram-node2,\
host-nodes=1-2,host-nodes=5,host-nodes=7,policy=bind \
-numa node,nodeid=2,cpus=28,cpus=30-31,memdev=ram-node2 \
-nographic -monitor unix:/tmp/test-monitor,server,nowait \
-no-acpi -boot c -usb -net none -serial none -parallel none
......@@ -1197,7 +1197,14 @@ mymain(void)
DO_TEST("blkiotune-device", QEMU_CAPS_NAME);
DO_TEST("cputune", QEMU_CAPS_NAME);
DO_TEST("cputune-zero-shares", QEMU_CAPS_NAME);
DO_TEST("numatune-memory", NONE);
DO_TEST("numatune-memnode", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM);
DO_TEST_FAILURE("numatune-memnode", NONE);
DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM);
DO_TEST_FAILURE("numatune-memnode-no-memory", NONE);
DO_TEST("numatune-auto-nodeset-invalid", NONE);
DO_TEST_PARSE_ERROR("numatune-memnode-nocpu", NONE);
DO_TEST_PARSE_ERROR("numatune-memnodes-problematic", NONE);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册