From: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> When a domain is configured with 'shared' memory backing: <memoryBacking> <access mode='shared'/> </memoryBacking> But no explicit NUMA configuration, let's configure a shared memory backend associated with default -numa. Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> --- src/qemu/qemu_command.c | 100 ++++++++++++------ .../fd-memory-no-numa-topology.args | 4 + 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 44ae8dcef7..f1235099b2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3254,26 +3254,21 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, static int -qemuBuildMemoryCellBackendStr(virDomainDefPtr def, - virQEMUDriverConfigPtr cfg, - size_t cell, - qemuDomainObjPrivatePtr priv, - virBufferPtr buf) +qemuBuildMemoryBackendStr(virDomainDefPtr def, + virQEMUDriverConfigPtr cfg, + const char *alias, + int targetNode, + unsigned long long memsize, + qemuDomainObjPrivatePtr priv, + virBufferPtr buf) { virJSONValuePtr props = NULL; - char *alias = NULL; - int ret = -1; - int rc; virDomainMemoryDef mem = { 0 }; - unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa, - cell); - - if (virAsprintf(&alias, "ram-node%zu", cell) < 0) - goto cleanup; + int rc, ret = -1; mem.size = memsize; - mem.targetNode = cell; - mem.info.alias = alias; + mem.targetNode = targetNode; + mem.info.alias = (char *)alias; if ((rc = qemuBuildMemoryBackendProps(&props, alias, cfg, priv->qemuCaps, def, &mem, priv->autoNodeset, false)) < 0) @@ -3284,9 +3279,30 @@ qemuBuildMemoryCellBackendStr(virDomainDefPtr def, ret = rc; +cleanup: + virJSONValueFree(props); + return ret; +} + + +static int +qemuBuildMemoryCellBackendStr(virDomainDefPtr def, + virQEMUDriverConfigPtr cfg, + size_t cell, + qemuDomainObjPrivatePtr priv, + virBufferPtr buf) +{ + char *alias = NULL; + int ret = -1; + unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa, cell); + + if (virAsprintf(&alias, "ram-node%zu", cell) < 0) + goto cleanup; + + ret = qemuBuildMemoryBackendStr(def, cfg, alias, cell, memsize, priv, buf); + cleanup: VIR_FREE(alias); - virJSONValueFree(props); return ret; } @@ -7590,6 +7606,17 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, size_t ncells = virDomainNumaGetNodeCount(def->numa); const long system_page_size = virGetSystemPageSizeKB(); bool numa_distances = false; + bool implicit = false; + + if (ncells == 0) { + if (def->mem.access == VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + ncells = 1; + implicit = true; + } else { + ret = 0; + goto cleanup; + } + } if (virDomainNumatuneHasPerNodeBinding(def->numa) && !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || @@ -7645,14 +7672,22 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { - if ((rc = qemuBuildMemoryCellBackendStr(def, cfg, i, priv, - &nodeBackends[i])) < 0) + + if (implicit) + rc = qemuBuildMemoryBackendStr(def, cfg, "ram-node", -1, + def->mem.total_memory, + priv, &nodeBackends[i]); + else + rc = qemuBuildMemoryCellBackendStr(def, cfg, i, + priv, &nodeBackends[i]); + if (rc < 0) goto cleanup; if (rc == 0) needBackend = true; } else { - if (virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) { + if (implicit || + virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Shared memory mapping is not supported " "with this QEMU")); @@ -7667,15 +7702,18 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, for (i = 0; i < ncells; i++) { VIR_FREE(cpumask); - if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i)))) - goto cleanup; - if (strchr(cpumask, ',') && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("disjoint NUMA cpu ranges are not supported " - "with this QEMU")); - goto cleanup; + if (!implicit) { + if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i)))) + goto cleanup; + + if (strchr(cpumask, ',') && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disjoint NUMA cpu ranges are not supported " + "with this QEMU")); + goto cleanup; + } } if (needBackend) { @@ -7694,7 +7732,8 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, } if (needBackend) - virBufferAsprintf(&buf, ",memdev=ram-node%zu", i); + virBufferAsprintf(&buf, implicit ? + ",memdev=ram-node" : ",memdev=ram-node%zu", i); else virBufferAsprintf(&buf, ",mem=%llu", virDomainNumaGetNodeMemorySize(def->numa, i) / 1024); @@ -7717,7 +7756,7 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, break; } - if (numa_distances) { + if (!implicit && numa_distances) { if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA_DIST)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("setting NUMA distances is not " @@ -10303,8 +10342,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, if (qemuBuildIOThreadCommandLine(cmd, def) < 0) goto error; - if (virDomainNumaGetNodeCount(def->numa) && - qemuBuildNumaArgStr(cfg, def, cmd, priv) < 0) + if (qemuBuildNumaArgStr(cfg, def, cmd, priv) < 0) goto error; if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, priv) < 0) diff --git a/tests/qemuxml2argvdata/fd-memory-no-numa-topology.args b/tests/qemuxml2argvdata/fd-memory-no-numa-topology.args index bd88daaa3b..400fb39cc6 100644 --- a/tests/qemuxml2argvdata/fd-memory-no-numa-topology.args +++ b/tests/qemuxml2argvdata/fd-memory-no-numa-topology.args @@ -11,6 +11,10 @@ QEMU_AUDIO_DRV=none \ -m 14336 \ -mem-prealloc \ -smp 8,sockets=8,cores=1,threads=1 \ +-object memory-backend-file,id=ram-node,\ +mem-path=/var/lib/libvirt/qemu/ram/libvirt/qemu/-1-instance-00000092/ram-node,\ +share=yes,size=15032385536 \ +-numa node,nodeid=0,memdev=ram-node \ -uuid 126f2720-6f8e-45ab-a886-ec9277079a67 \ -display none \ -no-user-config \ -- 2.18.0.129.ge3331758f1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list