* src/conf/domain_conf.h: Introduce one new struct for representing NUMA tuning related stuffs. * src/conf/domain_conf.c: Parse and format numatune XML. --- src/conf/domain_conf.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 22 ++++++++++++++ src/libvirt_private.syms | 2 + 3 files changed, 96 insertions(+), 0 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 02707dd..8d5e173 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -484,6 +484,11 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST, "paravirt", "smpsafe"); +VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST, + "strict", + "preferred", + "interleave"); + #define virDomainReportError(code, ...) \ virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) @@ -5875,6 +5880,51 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, } VIR_FREE(nodes); + /* Extract numatune if exists. */ + if ((n = virXPathNodeSet("./numatune", ctxt, NULL)) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot extract numatune nodes")); + goto error; + } + + if (n) { + tmp = virXPathString("string(./numatune/memory/@nodeset)", ctxt); + if (tmp) { + char *set = tmp; + int nodemasklen = VIR_DOMAIN_CPUMASK_LEN; + + if (VIR_ALLOC_N(def->numatune.memory.nodemask, nodemasklen) < 0) { + virReportOOMError(); + goto error; + } + + /* "nodeset" leads same syntax with "cpuset". */ + if (virDomainCpuSetParse((const char **)&set, + 0, def->numatune.memory.nodemask, + nodemasklen) < 0) + goto error; + VIR_FREE(tmp); + } else { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("nodeset for NUMA memory tuning must be set")); + goto error; + } + + tmp = virXPathString("string(./numatune/memory/@mode)", ctxt); + if (tmp) { + if ((def->numatune.memory.mode = + virDomainNumatuneMemModeTypeFromString(tmp)) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("Unsupported NUMA memory tuning mode '%s'"), + tmp); + goto error; + } + VIR_FREE(tmp); + } else { + def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; + } + } + n = virXPathNodeSet("./features/*", ctxt, &nodes); if (n < 0) goto error; @@ -9457,6 +9507,28 @@ char *virDomainDefFormat(virDomainDefPtr def, if (def->cputune.shares || def->cputune.vcpupin) virBufferAddLit(&buf, " </cputune>\n"); + if (def->numatune.memory.nodemask) + virBufferAddLit(&buf, " <numatune>\n"); + + if (def->numatune.memory.nodemask) { + char *nodemask = NULL; + nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask, + VIR_DOMAIN_CPUMASK_LEN); + if (nodemask == NULL) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("failed to format nodeset for NUMA memory tuning")); + goto cleanup; + } + + virBufferAsprintf(&buf, " <memory mode='%s' nodeset='%s'/>\n", + virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode), + nodemask); + VIR_FREE(nodemask); + } + + if (def->numatune.memory.nodemask) + virBufferAddLit(&buf, " </numatune>\n"); + if (def->sysinfo) virDomainSysinfoDefFormat(&buf, def->sysinfo); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1f4bf1d..3c54e8b 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1117,6 +1117,25 @@ virDomainVcpupinDefPtr virDomainVcpupinFindByVcpu(virDomainVcpupinDefPtr *def, int nvcpupin, int vcpu); +enum virDomainNumatuneMemMode { + VIR_DOMAIN_NUMATUNE_MEM_STRICT, + VIR_DOMAIN_NUMATUNE_MEM_PREFERRED, + VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE, + + VIR_DOMAIN_NUMATUNE_MEM_LAST +}; + +typedef struct _virDomainNumatuneDef virDomainNumatuneDef; +typedef virDomainNumatuneDef *virDomainNumatuneDefPtr; +struct _virDomainNumatuneDef { + struct { + char *nodemask; + int mode; + } memory; + + /* Future NUMA tuning related stuff should go here. */ +}; + /* * Guest VM main configuration * @@ -1156,6 +1175,8 @@ struct _virDomainDef { virDomainVcpupinDefPtr *vcpupin; } cputune; + virDomainNumatuneDef numatune; + /* These 3 are based on virDomainLifeCycleAction enum flags */ int onReboot; int onPoweroff; @@ -1564,6 +1585,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression) VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression) VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode) VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste) +VIR_ENUM_DECL(virDomainNumatuneMemMode) /* from libvirt.h */ VIR_ENUM_DECL(virDomainState) VIR_ENUM_DECL(virDomainNostateReason) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5202da3..ae18c0d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -310,6 +310,8 @@ virDomainNetIndexByMac; virDomainNetInsert; virDomainNetRemoveByMac; virDomainNetTypeToString; +virDomainNumatuneMemModeTypeFromString; +virDomainNumatuneMemModeTypeToString; virDomainObjAssignDef; virDomainObjCopyPersistentDef; virDomainObjGetPersistentDef; -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list