Re: [libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
Hi On Thu, Aug 16, 2018 at 12:48 PM Daniel P. Berrangé wrote: > > On Fri, Jul 13, 2018 at 03:28:08PM +0200, marcandre.lur...@redhat.com wrote: > > From: Marc-André Lureau > > > > When a domain is configured with 'shared' memory backing: > > > > > > > > > > > > But no explicit NUMA configuration, let's configure a shared memory > > backend associated with default -numa. > > > > 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-0092/ram-node,\ > > +share=yes,size=15032385536 \ > > +-numa node,nodeid=0,memdev=ram-node \ > > I'm not at all convinced it is safe todo this. We've been burnt in the > past by adding use of memory-backend objects causing migration to break > > > commit f309db1f4d51009bad0d32e12efc75530b66836b > Author: Michal Privoznik > Date: Thu Dec 18 12:36:48 2014 +0100 > > 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 > > This change doesn't really feel like it is required either. If the > user wants NUMA, then the XML can just be written to request a NUMA > topology with a single node. Better to be explicit in the XML rather > than silently adding things as a side effect Ok, let's drop this patch then. I'll modify "qemu: use memory-backend-memfd if possible" to make use of memfd differently, with explicit NUMA. > > Regards, > Daniel > -- > |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| > |: https://libvirt.org -o-https://fstop138.berrange.com :| > |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :| > > -- > libvir-list mailing list > libvir-list@redhat.com > https://www.redhat.com/mailman/listinfo/libvir-list -- Marc-André Lureau -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
On Thu, Aug 16, 2018 at 07:32:57AM -0400, John Ferlan wrote: > > > On 08/16/2018 06:31 AM, Marc-André Lureau wrote: > > Hi > > > > On Thu, Aug 16, 2018 at 4:35 AM, John Ferlan wrote: > >> > >> > >> On 07/13/2018 09:28 AM, marcandre.lur...@redhat.com wrote: > >>> From: Marc-André Lureau > >>> > >>> When a domain is configured with 'shared' memory backing: > >>> > >>> > >>> > >>> > >>> > >>> But no explicit NUMA configuration, let's configure a shared memory > >>> backend associated with default -numa. > >>> > >>> Signed-off-by: Marc-André Lureau > >>> --- > >>> src/qemu/qemu_command.c | 100 -- > >>> .../fd-memory-no-numa-topology.args | 4 + > >>> 2 files changed, 73 insertions(+), 31 deletions(-) > >>> > >> > >> NUMA, memory backends, and hugepages - not in my wheelhouse of > >> knowledge. Hopefully Michal and/or Pavel will take a look! > >> > >> Is it possible someone may not want this type of thing to happen? Is > > > > I assume someone that sets 'shared' memory mode may consider this as a bug > > fix. > > > >> there an upside or downside to this? What happens "today" when not > > > > You get non-shared memory > > > > So today someone asks for "shared" and then end up with "non-shared"? I > don't think that's apparent from the "access" description in: > > https://libvirt.org/formatdomain.html#elementsMemoryBacking > > Then again, not in my wheelhouse of knowledge, so maybe that's just one > of those givens. Of course that perhaps goes to your first answer of > this being a "bug fix". Not something that's apparent from the existing > documentation or commit description though. This probably should have > been it's own separate patch and not included in this series. If we can't honour the "shared" request, we should make sure libvirt reports an error and aborts startup. Regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
On 08/16/2018 06:31 AM, Marc-André Lureau wrote: > Hi > > On Thu, Aug 16, 2018 at 4:35 AM, John Ferlan wrote: >> >> >> On 07/13/2018 09:28 AM, marcandre.lur...@redhat.com wrote: >>> From: Marc-André Lureau >>> >>> When a domain is configured with 'shared' memory backing: >>> >>> >>> >>> >>> >>> But no explicit NUMA configuration, let's configure a shared memory >>> backend associated with default -numa. >>> >>> Signed-off-by: Marc-André Lureau >>> --- >>> src/qemu/qemu_command.c | 100 -- >>> .../fd-memory-no-numa-topology.args | 4 + >>> 2 files changed, 73 insertions(+), 31 deletions(-) >>> >> >> NUMA, memory backends, and hugepages - not in my wheelhouse of >> knowledge. Hopefully Michal and/or Pavel will take a look! >> >> Is it possible someone may not want this type of thing to happen? Is > > I assume someone that sets 'shared' memory mode may consider this as a bug > fix. > >> there an upside or downside to this? What happens "today" when not > > You get non-shared memory > So today someone asks for "shared" and then end up with "non-shared"? I don't think that's apparent from the "access" description in: https://libvirt.org/formatdomain.html#elementsMemoryBacking Then again, not in my wheelhouse of knowledge, so maybe that's just one of those givens. Of course that perhaps goes to your first answer of this being a "bug fix". Not something that's apparent from the existing documentation or commit description though. This probably should have been it's own separate patch and not included in this series. >> generated? And of course, what about migration concerns about >> unconditionally doing this for some target migration? > > True, this will break migration though if the target uses > numa/memory-backend-file. > > What do you suggest? > This needs to be configurable as we cannot break w/ migration. I'm not quite sure how we document this other than as Dan suggests that if someone wants NUMA, then they'll configure things properly. If this 'shared' ends up as 'non-shared' because NUMA isn't configured, then we should indicate that. If the adding some property to the element to indicate desire of 'shared' via usage of some (local) backing store which means the guest probably isn't very migrate-able, then so bit it. >> >>> 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, >> >> So the one "concern" I'd have here is some time in the future the @mem >> gets allocated and handled like a real device eventually calling >> virDomainDeviceInfoClear and that'd be a problem for the passed const >> char * string. Some future person's problem I guess! >> >>> + int targetNode, >>> + unsigned long long memsize, >>> + qemuDomainObjPrivatePtr priv, >>> + virBufferPtr buf) >> >> As much as a long name is a pain, is this more of a : >> >> qemuBuildMemorySharedDefaultBackendStr > > Why? > nm, I think when first reading for some reason I had this "separate" from the CellBackend call. [...] >>> +implicit = true; >>> +} else { >>> +ret = 0; >>> +goto cleanup; >>> +} >>> +} >> >> So if ncells == 0 && def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_SHARED, >> then we return 0 without doing the subsequent code? Is that expected? Is >> there something done later that may be necessary, needed, or assumed. > > No, before the patch, virDomainNumaGetNodeCount() is checked before > calling qemuBuildNumaArgStr(). Now it is handled inside in case > ncells==0 && def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_SHARED. > Ah, yes - I missed the check when looking at the changes -if (virDomainNumaGetNodeCount(def->numa) && -qemuBuildNumaArgStr(cfg, def, cmd, 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
Re: [libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
On Fri, Jul 13, 2018 at 03:28:08PM +0200, marcandre.lur...@redhat.com wrote: > From: Marc-André Lureau > > When a domain is configured with 'shared' memory backing: > > > > > > But no explicit NUMA configuration, let's configure a shared memory > backend associated with default -numa. > 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-0092/ram-node,\ > +share=yes,size=15032385536 \ > +-numa node,nodeid=0,memdev=ram-node \ I'm not at all convinced it is safe todo this. We've been burnt in the past by adding use of memory-backend objects causing migration to break commit f309db1f4d51009bad0d32e12efc75530b66836b Author: Michal Privoznik Date: Thu Dec 18 12:36:48 2014 +0100 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 This change doesn't really feel like it is required either. If the user wants NUMA, then the XML can just be written to request a NUMA topology with a single node. Better to be explicit in the XML rather than silently adding things as a side effect Regards, Daniel -- |: https://berrange.com -o-https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o-https://fstop138.berrange.com :| |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
Hi On Thu, Aug 16, 2018 at 4:35 AM, John Ferlan wrote: > > > On 07/13/2018 09:28 AM, marcandre.lur...@redhat.com wrote: >> From: Marc-André Lureau >> >> When a domain is configured with 'shared' memory backing: >> >> >> >> >> >> But no explicit NUMA configuration, let's configure a shared memory >> backend associated with default -numa. >> >> Signed-off-by: Marc-André Lureau >> --- >> src/qemu/qemu_command.c | 100 -- >> .../fd-memory-no-numa-topology.args | 4 + >> 2 files changed, 73 insertions(+), 31 deletions(-) >> > > NUMA, memory backends, and hugepages - not in my wheelhouse of > knowledge. Hopefully Michal and/or Pavel will take a look! > > Is it possible someone may not want this type of thing to happen? Is I assume someone that sets 'shared' memory mode may consider this as a bug fix. > there an upside or downside to this? What happens "today" when not You get non-shared memory > generated? And of course, what about migration concerns about > unconditionally doing this for some target migration? True, this will break migration though if the target uses numa/memory-backend-file. What do you suggest? > >> 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, > > So the one "concern" I'd have here is some time in the future the @mem > gets allocated and handled like a real device eventually calling > virDomainDeviceInfoClear and that'd be a problem for the passed const > char * string. Some future person's problem I guess! > >> + int targetNode, >> + unsigned long long memsize, >> + qemuDomainObjPrivatePtr priv, >> + virBufferPtr buf) > > As much as a long name is a pain, is this more of a : > > qemuBuildMemorySharedDefaultBackendStr Why? > >> { >> virJSONValuePtr props = NULL; >> -char *alias = NULL; >> -int ret = -1; >> -int rc; >> virDomainMemoryDef mem = { 0 }; >> -unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa, >> -cell); >> - >> -if (virAsprintf(, "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(, alias, cfg, >> priv->qemuCaps, >>def, , priv->autoNodeset, >> false)) < 0)> @@ -3284,9 +3279,30 @@ >> qemuBuildMemoryCellBackendStr(virDomainDefPtr def, >> >> ret = rc; >> >> +cleanup: > > Fails 'make check syntax-check' : > > maint.mk: Top-level labels should be indented by one space > make: *** [cfg.mk:898: sc_require_space_before_label] Error 1 argh, fixed > >> +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(, "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; > > Well, that's cheating for the subsequent for loop ;-) > >> +implicit = true; >> +} else { >> +ret = 0; >> +goto cleanup; >> +} >> +} > > So if ncells == 0 && def->mem.access
Re: [libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
On 07/13/2018 09:28 AM, marcandre.lur...@redhat.com wrote: > From: Marc-André Lureau > > When a domain is configured with 'shared' memory backing: > > > > > > But no explicit NUMA configuration, let's configure a shared memory > backend associated with default -numa. > > Signed-off-by: Marc-André Lureau > --- > src/qemu/qemu_command.c | 100 -- > .../fd-memory-no-numa-topology.args | 4 + > 2 files changed, 73 insertions(+), 31 deletions(-) > NUMA, memory backends, and hugepages - not in my wheelhouse of knowledge. Hopefully Michal and/or Pavel will take a look! Is it possible someone may not want this type of thing to happen? Is there an upside or downside to this? What happens "today" when not generated? And of course, what about migration concerns about unconditionally doing this for some target migration? > 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, So the one "concern" I'd have here is some time in the future the @mem gets allocated and handled like a real device eventually calling virDomainDeviceInfoClear and that'd be a problem for the passed const char * string. Some future person's problem I guess! > + int targetNode, > + unsigned long long memsize, > + qemuDomainObjPrivatePtr priv, > + virBufferPtr buf) As much as a long name is a pain, is this more of a : qemuBuildMemorySharedDefaultBackendStr > { > virJSONValuePtr props = NULL; > -char *alias = NULL; > -int ret = -1; > -int rc; > virDomainMemoryDef mem = { 0 }; > -unsigned long long memsize = virDomainNumaGetNodeMemorySize(def->numa, > -cell); > - > -if (virAsprintf(, "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(, alias, cfg, priv->qemuCaps, >def, , priv->autoNodeset, > false)) < 0)> @@ -3284,9 +3279,30 @@ > qemuBuildMemoryCellBackendStr(virDomainDefPtr def, > > ret = rc; > > +cleanup: Fails 'make check syntax-check' : maint.mk: Top-level labels should be indented by one space make: *** [cfg.mk:898: sc_require_space_before_label] Error 1 > +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(, "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; Well, that's cheating for the subsequent for loop ;-) > +implicit = true; > +} else { > +ret = 0; > +goto cleanup; > +} > +} So if ncells == 0 && def->mem.access != VIR_DOMAIN_MEMORY_ACCESS_SHARED, then we return 0 without doing the subsequent code? Is that expected? Is there something done later that may be necessary, needed, or assumed. > > if (virDomainNumatuneHasPerNodeBinding(def->numa) && > !(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || > @@ -7645,14 +7672,22 @@ qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, > if (virQEMUCapsGet(qemuCaps,
[libvirt] [RFC PATCH 01/17] qemu: setup shared memory without explicit numa configuration
From: Marc-André Lureau When a domain is configured with 'shared' memory backing: But no explicit NUMA configuration, let's configure a shared memory backend associated with default -numa. Signed-off-by: Marc-André Lureau --- 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(, "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(, alias, cfg, priv->qemuCaps, def, , 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(, "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, -[i])) < 0) + +if (implicit) +rc = qemuBuildMemoryBackendStr(def, cfg, "ram-node", -1, + def->mem.total_memory, + priv, [i]); +else +rc = qemuBuildMemoryCellBackendStr(def, cfg, i, + priv, [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)) { -