[libvirt] [PATCH 1/2] conf: Add support for preallocated fd memory
Michal Privoznik
mprivozn at redhat.com
Tue Oct 4 15:07:16 UTC 2016
On 29.09.2016 10:56, Jaroslav Safka wrote:
> This first change introduces xml parsing support for preallocated
> shared file descriptor based memory backing.
> It allows vhost-user to be used without hugepages.
>
> New xml elements:
> <memoryBacking>
> <source type='file|anonymous' path='/path/to/qemu/' />
> <access Mode='shared|private'/>
> <allocation mode='immediate|ondemand'/>
> </memoryBacking>
Okay, this is definitely interesting approach (not only because while
reviewing this, I've found an old branch in my git where I've started to
work on this).
Frankly, I don't know if this is a good API or not. Historically, we
required Dan's ACK on XML schema :-)
btw: s/Mode/mode/ ;-)
> ---
> docs/schemas/domaincommon.rng | 37 +++++
> src/conf/domain_conf.c | 149 ++++++++++++++++-----
> src/conf/domain_conf.h | 34 +++++
> .../qemuxml2argv-memorybacking-set.xml | 32 +++++
> .../qemuxml2argv-memorybacking-unset.xml | 32 +++++
> .../qemuxml2xmlout-memorybacking-set.xml | 40 ++++++
> .../qemuxml2xmlout-memorybacking-unset.xml | 40 ++++++
> tests/qemuxml2xmltest.c | 3 +
> 8 files changed, 334 insertions(+), 33 deletions(-)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml
> create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml
> create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml
You need to update the docs too. formatdomain.html.in to be more precise.
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index a06da46..7f73569 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -16179,48 +16194,101 @@ virDomainDefParseXML(xmlDocPtr xml,
> }
> VIR_FREE(tmp);
>
> - if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) {
> - virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("cannot extract hugepages nodes"));
> - goto error;
> + tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt);
> + if (tmp) {
> + if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) < 0) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("unknown memoryBacking/source/type '%s'"), tmp);
> + goto error;
> + }
> + VIR_FREE(tmp);
> + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) {
> + tmp = virXPathString("string(./memoryBacking/source/@path)", ctxt);
> + if (!tmp && VIR_STRDUP(tmp, VIR_DOMAIN_MEMORY_DEFAULT_PATH) < 0)
> + goto error;
> +
> + def->mem.mem_path = tmp;
> + tmp = NULL;
> + }
> }
>
> - if (n) {
> - if (VIR_ALLOC_N(def->mem.hugepages, n) < 0)
> + tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt);
> + if (tmp) {
> + if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) < 0) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("unknown memoryBacking/access/mode '%s'"), tmp);
> goto error;
> + }
> + VIR_FREE(tmp);
> + }
>
> - for (i = 0; i < n; i++) {
> - if (virDomainHugepagesParseXML(nodes[i], ctxt,
> - &def->mem.hugepages[i]) < 0)
> + tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt);
> + if (tmp) {
> + if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) < 0) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("unknown memoryBacking/allocation/mode '%s'"), tmp);
> + goto error;
> + }
> + VIR_FREE(tmp);
> + }
> +
> + if (virXPathNode("./memoryBacking/hugepages", ctxt)) {
> + /* hugepages will be used */
> +
> + if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("hugepages are not allowed with memory allocation ondemand"));
> + goto error;
> + }
> +
> + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("hugepages are not allowed with anonymous memory source"));
> + goto error;
> + }
> +
> + if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("cannot extract hugepages nodes"));
> + goto error;
> + }
These types of checks would normally go to post parse callback.
> +
> + if (n) {
> + if (VIR_ALLOC_N(def->mem.hugepages, n) < 0)
> goto error;
> - def->mem.nhugepages++;
>
> - for (j = 0; j < i; j++) {
> - if (def->mem.hugepages[i].nodemask &&
> - def->mem.hugepages[j].nodemask &&
> - virBitmapOverlaps(def->mem.hugepages[i].nodemask,
> - def->mem.hugepages[j].nodemask)) {
> - virReportError(VIR_ERR_XML_DETAIL,
> - _("nodeset attribute of hugepages "
> - "of sizes %llu and %llu intersect"),
> - def->mem.hugepages[i].size,
> - def->mem.hugepages[j].size);
> - goto error;
> - } else if (!def->mem.hugepages[i].nodemask &&
> - !def->mem.hugepages[j].nodemask) {
> - virReportError(VIR_ERR_XML_DETAIL,
> - _("two master hugepages detected: "
> - "%llu and %llu"),
> - def->mem.hugepages[i].size,
> - def->mem.hugepages[j].size);
> + for (i = 0; i < n; i++) {
> + if (virDomainHugepagesParseXML(nodes[i], ctxt,
> + &def->mem.hugepages[i]) < 0)
> goto error;
> + def->mem.nhugepages++;
> +
> + for (j = 0; j < i; j++) {
> + if (def->mem.hugepages[i].nodemask &&
> + def->mem.hugepages[j].nodemask &&
> + virBitmapOverlaps(def->mem.hugepages[i].nodemask,
> + def->mem.hugepages[j].nodemask)) {
> + virReportError(VIR_ERR_XML_DETAIL,
> + _("nodeset attribute of hugepages "
> + "of sizes %llu and %llu intersect"),
> + def->mem.hugepages[i].size,
> + def->mem.hugepages[j].size);
> + goto error;
> + } else if (!def->mem.hugepages[i].nodemask &&
> + !def->mem.hugepages[j].nodemask) {
> + virReportError(VIR_ERR_XML_DETAIL,
> + _("two master hugepages detected: "
> + "%llu and %llu"),
> + def->mem.hugepages[i].size,
> + def->mem.hugepages[j].size);
> + goto error;
> + }
> }
> }
> - }
>
> - VIR_FREE(nodes);
> - } else {
> - if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) {
> + VIR_FREE(nodes);
> + } else {
> + /* no hugepage pages */
> if (VIR_ALLOC(def->mem.hugepages) < 0)
> goto error;
>
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index d2065cf..f1290a3 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -3073,6 +3104,9 @@ VIR_ENUM_DECL(virDomainTPMModel)
> VIR_ENUM_DECL(virDomainTPMBackend)
> VIR_ENUM_DECL(virDomainMemoryModel)
> VIR_ENUM_DECL(virDomainMemoryBackingModel)
> +VIR_ENUM_DECL(virDomainMemorySource)
> +VIR_ENUM_DECL(virDomainMemoryAccess)
> +VIR_ENUM_DECL(virDomainMemoryAllocation)
These macros declare vir*TypeFromString() and vir*TypeToString()
functions. Because they are in the header file, we should update the
libvirt_private.syms too (even though these functions are not used
anywere else just yet).
The rest of the code looks okay (even in 2/2).
Michal
More information about the libvir-list
mailing list