mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
numatune: Encapsulate numatune configuration in order to unify results
There were numerous places where numatune configuration (and thus domain config as well) was changed in different ways. On some places this even resulted in persistent domain definition not to be stable (it would change with daemon's restart). In order to uniformly change how numatune config is dealt with, all the internals are now accessible directly only in numatune_conf.c and outside this file accessors must be used. Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
e764ec7ae3
commit
93e82727ec
@ -25,6 +25,7 @@ src/conf/netdev_vlan_conf.c
|
||||
src/conf/netdev_vport_profile_conf.c
|
||||
src/conf/network_conf.c
|
||||
src/conf/node_device_conf.c
|
||||
src/conf/numatune_conf.c
|
||||
src/conf/nwfilter_conf.c
|
||||
src/conf/nwfilter_params.c
|
||||
src/conf/object_event.c
|
||||
|
@ -2102,7 +2102,7 @@ void virDomainDefFree(virDomainDefPtr def)
|
||||
|
||||
virDomainVcpuPinDefFree(def->cputune.emulatorpin);
|
||||
|
||||
virBitmapFree(def->numatune.memory.nodemask);
|
||||
virDomainNumatuneFree(def->numatune);
|
||||
|
||||
virSysinfoDefFree(def->sysinfo);
|
||||
|
||||
@ -11332,7 +11332,6 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
unsigned long count;
|
||||
bool uuid_generated = false;
|
||||
virHashTablePtr bootHash = NULL;
|
||||
xmlNodePtr cur;
|
||||
bool usb_none = false;
|
||||
bool usb_other = false;
|
||||
bool usb_master = false;
|
||||
@ -11794,123 +11793,8 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract numatune if exists. */
|
||||
if ((n = virXPathNodeSet("./numatune", ctxt, &nodes)) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("cannot extract numatune nodes"));
|
||||
if (virDomainNumatuneParseXML(def, ctxt) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (n > 1) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("only one numatune is supported"));
|
||||
VIR_FREE(nodes);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
cur = nodes[0]->children;
|
||||
while (cur != NULL) {
|
||||
if (cur->type == XML_ELEMENT_NODE) {
|
||||
if (xmlStrEqual(cur->name, BAD_CAST "memory")) {
|
||||
char *mode = NULL;
|
||||
char *placement = NULL;
|
||||
char *nodeset = NULL;
|
||||
|
||||
mode = virXMLPropString(cur, "mode");
|
||||
if (mode) {
|
||||
if ((def->numatune.memory.mode =
|
||||
virDomainNumatuneMemModeTypeFromString(mode)) < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported NUMA memory "
|
||||
"tuning mode '%s'"),
|
||||
mode);
|
||||
VIR_FREE(mode);
|
||||
goto error;
|
||||
}
|
||||
VIR_FREE(mode);
|
||||
} else {
|
||||
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
||||
}
|
||||
|
||||
nodeset = virXMLPropString(cur, "nodeset");
|
||||
if (nodeset) {
|
||||
if (virBitmapParse(nodeset,
|
||||
0,
|
||||
&def->numatune.memory.nodemask,
|
||||
VIR_DOMAIN_CPUMASK_LEN) < 0) {
|
||||
VIR_FREE(nodeset);
|
||||
goto error;
|
||||
}
|
||||
VIR_FREE(nodeset);
|
||||
}
|
||||
|
||||
placement = virXMLPropString(cur, "placement");
|
||||
int placement_mode = 0;
|
||||
if (placement) {
|
||||
if ((placement_mode =
|
||||
virDomainNumatunePlacementTypeFromString(placement)) < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported memory placement "
|
||||
"mode '%s'"), placement);
|
||||
VIR_FREE(placement);
|
||||
goto error;
|
||||
}
|
||||
VIR_FREE(placement);
|
||||
} else if (def->numatune.memory.nodemask) {
|
||||
/* Defaults to "static" if nodeset is specified. */
|
||||
placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
} else {
|
||||
/* Defaults to "placement" of <vcpu> if nodeset is
|
||||
* not specified.
|
||||
*/
|
||||
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
|
||||
placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
else
|
||||
placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
|
||||
}
|
||||
|
||||
if (placement_mode == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC &&
|
||||
!def->numatune.memory.nodemask) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("nodeset for NUMA memory tuning must be set "
|
||||
"if 'placement' is 'static'"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Ignore 'nodeset' if 'placement' is 'auto' finally */
|
||||
if (placement_mode == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
|
||||
virBitmapFree(def->numatune.memory.nodemask);
|
||||
def->numatune.memory.nodemask = NULL;
|
||||
}
|
||||
|
||||
/* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
|
||||
* is not specified and 'placement' of <numatune> is specified.
|
||||
*/
|
||||
if (placement_mode == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
|
||||
!def->cpumask)
|
||||
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
|
||||
|
||||
def->numatune.memory.placement_mode = placement_mode;
|
||||
} else {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("unsupported XML element %s"),
|
||||
(const char *)cur->name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
} else {
|
||||
/* Defaults NUMA memory placement mode to 'auto' if no <numatune>
|
||||
* and 'placement' of <vcpu> is 'auto'.
|
||||
*/
|
||||
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
|
||||
def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
|
||||
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
||||
}
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
|
||||
if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
@ -17527,30 +17411,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
||||
def->cputune.emulator_period || def->cputune.emulator_quota)
|
||||
virBufferAddLit(buf, "</cputune>\n");
|
||||
|
||||
if (def->numatune.memory.nodemask ||
|
||||
def->numatune.memory.placement_mode) {
|
||||
const char *mode;
|
||||
char *nodemask = NULL;
|
||||
const char *placement;
|
||||
|
||||
virBufferAddLit(buf, "<numatune>\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
mode = virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode);
|
||||
virBufferAsprintf(buf, "<memory mode='%s' ", mode);
|
||||
|
||||
if (def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
|
||||
if (!(nodemask = virBitmapFormat(def->numatune.memory.nodemask)))
|
||||
goto error;
|
||||
virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
|
||||
VIR_FREE(nodemask);
|
||||
} else if (def->numatune.memory.placement_mode) {
|
||||
placement = virDomainNumatunePlacementTypeToString(def->numatune.memory.placement_mode);
|
||||
virBufferAsprintf(buf, "placement='%s'/>\n", placement);
|
||||
}
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</numatune>\n");
|
||||
}
|
||||
if (virDomainNumatuneFormatXML(buf, def->numatune) < 0)
|
||||
goto error;
|
||||
|
||||
if (def->resource)
|
||||
virDomainResourceDefFormat(buf, def->resource);
|
||||
@ -19847,3 +19709,16 @@ virDomainObjSetMetadata(virDomainObjPtr vm,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
virDomainDefNeedsPlacementAdvice(virDomainDefPtr def)
|
||||
{
|
||||
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
|
||||
return true;
|
||||
|
||||
if (virDomainNumatuneHasPlacementAuto(def->numatune))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -67,6 +67,9 @@ typedef virDomainFSDef *virDomainFSDefPtr;
|
||||
typedef struct _virDomainNetDef virDomainNetDef;
|
||||
typedef virDomainNetDef *virDomainNetDefPtr;
|
||||
|
||||
typedef struct _virDomainNumatune virDomainNumatune;
|
||||
typedef virDomainNumatune *virDomainNumatunePtr;
|
||||
|
||||
typedef struct _virDomainInputDef virDomainInputDef;
|
||||
typedef virDomainInputDef *virDomainInputDefPtr;
|
||||
|
||||
@ -1897,7 +1900,7 @@ struct _virDomainDef {
|
||||
virDomainVcpuPinDefPtr emulatorpin;
|
||||
} cputune;
|
||||
|
||||
virDomainNumatune numatune;
|
||||
virDomainNumatunePtr numatune;
|
||||
virDomainResourceDefPtr resource;
|
||||
virDomainIdMapDef idmap;
|
||||
|
||||
@ -2717,4 +2720,7 @@ int virDomainObjSetMetadata(virDomainObjPtr vm,
|
||||
const char *configDir,
|
||||
unsigned int flags);
|
||||
|
||||
bool virDomainDefNeedsPlacementAdvice(virDomainDefPtr def)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
#endif /* __DOMAIN_CONF_H */
|
||||
|
@ -24,6 +24,12 @@
|
||||
|
||||
#include "numatune_conf.h"
|
||||
|
||||
#include "domain_conf.h"
|
||||
#include "viralloc.h"
|
||||
#include "virstring.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_DOMAIN
|
||||
|
||||
VIR_ENUM_IMPL(virDomainNumatuneMemMode,
|
||||
VIR_DOMAIN_NUMATUNE_MEM_LAST,
|
||||
"strict",
|
||||
@ -35,3 +41,315 @@ VIR_ENUM_IMPL(virDomainNumatunePlacement,
|
||||
"default",
|
||||
"static",
|
||||
"auto");
|
||||
|
||||
struct _virDomainNumatune {
|
||||
struct {
|
||||
virBitmapPtr nodeset;
|
||||
virDomainNumatuneMemMode mode;
|
||||
virDomainNumatunePlacement placement;
|
||||
} memory; /* pinning for all the memory */
|
||||
|
||||
/* Future NUMA tuning related stuff should go here. */
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
virDomainNumatuneParseXML(virDomainDefPtr def,
|
||||
xmlXPathContextPtr ctxt)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
int mode = -1;
|
||||
int n = 0;
|
||||
int placement = -1;
|
||||
int ret = -1;
|
||||
virBitmapPtr nodeset = NULL;
|
||||
xmlNodePtr node = NULL;
|
||||
|
||||
if (virXPathInt("count(./numatune)", ctxt, &n) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("cannot extract numatune nodes"));
|
||||
goto cleanup;
|
||||
} else if (n > 1) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("only one numatune is supported"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
node = virXPathNode("./numatune/memory[1]", ctxt);
|
||||
|
||||
if (def->numatune) {
|
||||
virDomainNumatuneFree(def->numatune);
|
||||
def->numatune = NULL;
|
||||
}
|
||||
|
||||
if (!node && def->placement_mode != VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
|
||||
return 0;
|
||||
|
||||
if (!node) {
|
||||
/* We know that def->placement_mode is "auto" if we're here */
|
||||
if (virDomainNumatuneSet(def, VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO,
|
||||
-1, NULL) < 0)
|
||||
goto cleanup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = virXMLPropString(node, "mode");
|
||||
if (tmp) {
|
||||
mode = virDomainNumatuneMemModeTypeFromString(tmp);
|
||||
if (mode < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported NUMA memory tuning mode '%s'"),
|
||||
tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
VIR_FREE(tmp);
|
||||
|
||||
tmp = virXMLPropString(node, "placement");
|
||||
if (tmp) {
|
||||
placement = virDomainNumatunePlacementTypeFromString(tmp);
|
||||
if (placement < 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported NUMA memory placement mode '%s'"),
|
||||
tmp);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
VIR_FREE(tmp);
|
||||
|
||||
tmp = virXMLPropString(node, "nodeset");
|
||||
if (tmp && virBitmapParse(tmp, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||
goto cleanup;
|
||||
VIR_FREE(tmp);
|
||||
|
||||
if (virDomainNumatuneSet(def, placement, mode, nodeset) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!n) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
virBitmapFree(nodeset);
|
||||
VIR_FREE(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
virDomainNumatuneFormatXML(virBufferPtr buf,
|
||||
virDomainNumatunePtr numatune)
|
||||
{
|
||||
const char *tmp = NULL;
|
||||
char *nodeset = NULL;
|
||||
|
||||
if (!numatune)
|
||||
return 0;
|
||||
|
||||
virBufferAddLit(buf, "<numatune>\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
|
||||
tmp = virDomainNumatuneMemModeTypeToString(numatune->memory.mode);
|
||||
virBufferAsprintf(buf, "<memory mode='%s' ", tmp);
|
||||
|
||||
if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
|
||||
if (!(nodeset = virBitmapFormat(numatune->memory.nodeset)))
|
||||
return -1;
|
||||
virBufferAsprintf(buf, "nodeset='%s'/>\n", nodeset);
|
||||
VIR_FREE(nodeset);
|
||||
} else if (numatune->memory.placement) {
|
||||
tmp = virDomainNumatunePlacementTypeToString(numatune->memory.placement);
|
||||
virBufferAsprintf(buf, "placement='%s'/>\n", tmp);
|
||||
}
|
||||
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</numatune>\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
virDomainNumatuneFree(virDomainNumatunePtr numatune)
|
||||
{
|
||||
if (!numatune)
|
||||
return;
|
||||
|
||||
virBitmapFree(numatune->memory.nodeset);
|
||||
|
||||
VIR_FREE(numatune);
|
||||
}
|
||||
|
||||
virDomainNumatuneMemMode
|
||||
virDomainNumatuneGetMode(virDomainNumatunePtr numatune)
|
||||
{
|
||||
return numatune ? numatune->memory.mode : 0;
|
||||
}
|
||||
|
||||
virBitmapPtr
|
||||
virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr auto_nodeset)
|
||||
{
|
||||
if (!numatune)
|
||||
return NULL;
|
||||
|
||||
if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
|
||||
return auto_nodeset;
|
||||
|
||||
/*
|
||||
* This weird logic has the same meaning as switch with
|
||||
* auto/static/default, but can be more readably changed later.
|
||||
*/
|
||||
if (numatune->memory.placement != VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC)
|
||||
return NULL;
|
||||
|
||||
return numatune->memory.nodeset;
|
||||
}
|
||||
|
||||
char *
|
||||
virDomainNumatuneFormatNodeset(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr auto_nodeset)
|
||||
{
|
||||
return virBitmapFormat(virDomainNumatuneGetNodeset(numatune,
|
||||
auto_nodeset));
|
||||
}
|
||||
|
||||
int
|
||||
virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr auto_nodeset,
|
||||
char **mask)
|
||||
{
|
||||
*mask = NULL;
|
||||
|
||||
if (!numatune)
|
||||
return 0;
|
||||
|
||||
if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO &&
|
||||
!auto_nodeset) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Advice from numad is needed in case of "
|
||||
"automatic numa placement"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
*mask = virDomainNumatuneFormatNodeset(numatune, auto_nodeset);
|
||||
if (!*mask)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
virDomainNumatuneSet(virDomainDefPtr def,
|
||||
int placement,
|
||||
int mode,
|
||||
virBitmapPtr nodeset)
|
||||
{
|
||||
bool create = !def->numatune; /* Whether we are creating new struct */
|
||||
int ret = -1;
|
||||
virDomainNumatunePtr numatune = NULL;
|
||||
|
||||
/* No need to do anything in this case */
|
||||
if (mode == -1 && placement == -1 && !nodeset)
|
||||
return 0;
|
||||
|
||||
/* Range checks */
|
||||
if (mode != -1 &&
|
||||
(mode < 0 || mode >= VIR_DOMAIN_NUMATUNE_MEM_LAST)) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported numatune mode '%d'"),
|
||||
mode);
|
||||
goto cleanup;
|
||||
}
|
||||
if (placement != -1 &&
|
||||
(placement < 0 || placement >= VIR_DOMAIN_NUMATUNE_PLACEMENT_LAST)) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
_("Unsupported numatune placement '%d'"),
|
||||
mode);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (create && VIR_ALLOC(def->numatune) < 0)
|
||||
goto cleanup;
|
||||
numatune = def->numatune;
|
||||
|
||||
if (create) {
|
||||
/* Defaults for new struct */
|
||||
if (mode == -1)
|
||||
mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
||||
|
||||
if (placement == -1)
|
||||
placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT;
|
||||
}
|
||||
|
||||
if (mode != -1)
|
||||
numatune->memory.mode = mode;
|
||||
if (nodeset) {
|
||||
virBitmapFree(numatune->memory.nodeset);
|
||||
numatune->memory.nodeset = virBitmapNewCopy(nodeset);
|
||||
if (!numatune->memory.nodeset)
|
||||
goto cleanup;
|
||||
if (placement == -1)
|
||||
placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
}
|
||||
|
||||
if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT) {
|
||||
if (numatune->memory.nodeset ||
|
||||
def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
|
||||
placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
else
|
||||
placement = VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
|
||||
}
|
||||
|
||||
if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC &&
|
||||
!numatune->memory.nodeset) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("nodeset for NUMA memory tuning must be set "
|
||||
"if 'placement' is 'static'"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
|
||||
virBitmapFree(numatune->memory.nodeset);
|
||||
numatune->memory.nodeset = NULL;
|
||||
if (!def->cpumask)
|
||||
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
|
||||
}
|
||||
|
||||
if (placement != -1)
|
||||
numatune->memory.placement = placement;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
virDomainNumatuneEquals(virDomainNumatunePtr n1,
|
||||
virDomainNumatunePtr n2)
|
||||
{
|
||||
if (!n1 && !n2)
|
||||
return true;
|
||||
|
||||
if (!n1 || !n2)
|
||||
return false;
|
||||
|
||||
if (n1->memory.mode != n2->memory.mode)
|
||||
return false;
|
||||
|
||||
if (n1->memory.placement != n2->memory.placement)
|
||||
return false;
|
||||
|
||||
return virBitmapEqual(n1->memory.nodeset, n2->memory.nodeset);
|
||||
}
|
||||
|
||||
bool
|
||||
virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune)
|
||||
{
|
||||
if (!numatune)
|
||||
return false;
|
||||
|
||||
if (numatune->memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -23,9 +23,25 @@
|
||||
#ifndef __NUMATUNE_CONF_H__
|
||||
# define __NUMATUNE_CONF_H__
|
||||
|
||||
# include <libxml/xpath.h>
|
||||
|
||||
# include "internal.h"
|
||||
# include "virutil.h"
|
||||
# include "virbitmap.h"
|
||||
# include "virbuffer.h"
|
||||
|
||||
/*
|
||||
* Since numatune configuration is closely bound to the whole config,
|
||||
* and because we don't have separate domain_conf headers for
|
||||
* typedefs, structs and functions, we need to have a forward
|
||||
* declaration here for virDomainDef due to circular dependencies.
|
||||
*/
|
||||
typedef struct _virDomainDef virDomainDef;
|
||||
typedef virDomainDef *virDomainDefPtr;
|
||||
|
||||
|
||||
typedef struct _virDomainNumatune virDomainNumatune;
|
||||
typedef virDomainNumatune *virDomainNumatunePtr;
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT = 0,
|
||||
@ -36,19 +52,51 @@ typedef enum {
|
||||
} virDomainNumatunePlacement;
|
||||
|
||||
VIR_ENUM_DECL(virDomainNumatunePlacement)
|
||||
|
||||
VIR_ENUM_DECL(virDomainNumatuneMemMode)
|
||||
|
||||
typedef struct _virDomainNumatune virDomainNumatune;
|
||||
typedef virDomainNumatune *virDomainNumatunePtr;
|
||||
struct _virDomainNumatune {
|
||||
struct {
|
||||
virBitmapPtr nodemask;
|
||||
int mode; /* enum virDomainNumatuneMemMode */
|
||||
int placement_mode; /* enum virDomainNumatunePlacement */
|
||||
} memory; /* pinning for all the memory */
|
||||
|
||||
/* Future NUMA tuning related stuff should go here. */
|
||||
};
|
||||
void virDomainNumatuneFree(virDomainNumatunePtr numatune);
|
||||
|
||||
/*
|
||||
* XML Parse/Format functions
|
||||
*/
|
||||
int virDomainNumatuneParseXML(virDomainDefPtr def, xmlXPathContextPtr ctxt)
|
||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||
|
||||
int virDomainNumatuneFormatXML(virBufferPtr buf, virDomainNumatunePtr numatune)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
virDomainNumatuneMemMode virDomainNumatuneGetMode(virDomainNumatunePtr numatune);
|
||||
|
||||
virBitmapPtr virDomainNumatuneGetNodeset(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr auto_nodeset);
|
||||
|
||||
/*
|
||||
* Formatters
|
||||
*/
|
||||
char *virDomainNumatuneFormatNodeset(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr auto_nodeset);
|
||||
|
||||
int virDomainNumatuneMaybeFormatNodeset(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr auto_nodeset,
|
||||
char **mask);
|
||||
|
||||
/*
|
||||
* Setters
|
||||
*/
|
||||
int virDomainNumatuneSet(virDomainDefPtr def, int placement,
|
||||
int mode, virBitmapPtr nodeset)
|
||||
ATTRIBUTE_NONNULL(1);
|
||||
|
||||
/*
|
||||
* Other accessors
|
||||
*/
|
||||
bool virDomainNumatuneEquals(virDomainNumatunePtr n1,
|
||||
virDomainNumatunePtr n2);
|
||||
|
||||
bool virDomainNumatuneHasPlacementAuto(virDomainNumatunePtr numatune);
|
||||
|
||||
#endif /* __NUMATUNE_CONF_H__ */
|
||||
|
@ -200,6 +200,7 @@ virDomainDefGetDefaultEmulator;
|
||||
virDomainDefGetSecurityLabelDef;
|
||||
virDomainDefMaybeAddController;
|
||||
virDomainDefMaybeAddInput;
|
||||
virDomainDefNeedsPlacementAdvice;
|
||||
virDomainDefNew;
|
||||
virDomainDefParseFile;
|
||||
virDomainDefParseNode;
|
||||
@ -607,10 +608,20 @@ virNodeDeviceObjUnlock;
|
||||
|
||||
|
||||
# conf/numatune_conf.h
|
||||
virDomainNumatuneEquals;
|
||||
virDomainNumatuneFormatNodeset;
|
||||
virDomainNumatuneFormatXML;
|
||||
virDomainNumatuneFree;
|
||||
virDomainNumatuneGetMode;
|
||||
virDomainNumatuneGetNodeset;
|
||||
virDomainNumatuneHasPlacementAuto;
|
||||
virDomainNumatuneMaybeFormatNodeset;
|
||||
virDomainNumatuneMemModeTypeFromString;
|
||||
virDomainNumatuneMemModeTypeToString;
|
||||
virDomainNumatuneParseXML;
|
||||
virDomainNumatunePlacementTypeFromString;
|
||||
virDomainNumatunePlacementTypeToString;
|
||||
virDomainNumatuneSet;
|
||||
|
||||
|
||||
# conf/nwfilter_conf.h
|
||||
|
@ -79,22 +79,11 @@ static int virLXCCgroupSetupCpusetTune(virDomainDefPtr def,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((def->numatune.memory.nodemask ||
|
||||
(def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) &&
|
||||
def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
|
||||
if (def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
|
||||
mask = virBitmapFormat(nodemask);
|
||||
else
|
||||
mask = virBitmapFormat(def->numatune.memory.nodemask);
|
||||
if (virDomainNumatuneMaybeFormatNodeset(def->numatune, nodemask, &mask) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!mask)
|
||||
return -1;
|
||||
|
||||
if (virCgroupSetCpusetMems(cgroup, mask) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
if (mask && virCgroupSetCpusetMems(cgroup, mask) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
|
@ -653,10 +653,7 @@ static int virLXCControllerGetNumadAdvice(virLXCControllerPtr ctrl,
|
||||
/* Get the advisory nodeset from numad if 'placement' of
|
||||
* either <vcpu> or <numatune> is 'auto'.
|
||||
*/
|
||||
if ((ctrl->def->placement_mode ==
|
||||
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
|
||||
(ctrl->def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) {
|
||||
if (virDomainDefNeedsPlacementAdvice(ctrl->def)) {
|
||||
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
|
||||
ctrl->def->mem.cur_balloon);
|
||||
if (!nodeset)
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* lxc_native.c: LXC native configuration import
|
||||
*
|
||||
* Copyright (c) 2014 Red Hat, Inc.
|
||||
* Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -708,6 +709,7 @@ static int
|
||||
lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties)
|
||||
{
|
||||
virConfValuePtr value;
|
||||
virBitmapPtr nodeset = NULL;
|
||||
|
||||
if ((value = virConfGetValue(properties, "lxc.cgroup.cpuset.cpus")) &&
|
||||
value->str) {
|
||||
@ -719,12 +721,15 @@ lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties)
|
||||
}
|
||||
|
||||
if ((value = virConfGetValue(properties, "lxc.cgroup.cpuset.mems")) &&
|
||||
value->str) {
|
||||
def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
||||
if (virBitmapParse(value->str, 0, &def->numatune.memory.nodemask,
|
||||
VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||
value->str) {
|
||||
if (virBitmapParse(value->str, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||
return -1;
|
||||
if (virDomainNumatuneSet(def, VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC,
|
||||
VIR_DOMAIN_NUMATUNE_MEM_STRICT, nodeset) < 0) {
|
||||
virBitmapFree(nodeset);
|
||||
return -1;
|
||||
}
|
||||
virBitmapFree(nodeset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2078,12 +2078,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (old->numatune.memory.mode != new->numatune.memory.mode ||
|
||||
old->numatune.memory.placement_mode != new->numatune.memory.placement_mode ||
|
||||
((old->numatune.memory.nodemask != NULL || new->numatune.memory.nodemask != NULL) &&
|
||||
(old->numatune.memory.nodemask == NULL || new->numatune.memory.nodemask == NULL ||
|
||||
!virBitmapEqual(old->numatune.memory.nodemask, new->numatune.memory.nodemask)))){
|
||||
|
||||
if (!virDomainNumatuneEquals(old->numatune, new->numatune)) {
|
||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||
_("numa parameters are not supported "
|
||||
"by parallels driver"));
|
||||
|
@ -601,23 +601,14 @@ qemuSetupCpusetCgroup(virDomainObjPtr vm,
|
||||
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
|
||||
return 0;
|
||||
|
||||
if ((vm->def->numatune.memory.nodemask ||
|
||||
(vm->def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) &&
|
||||
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
|
||||
if (virDomainNumatuneMaybeFormatNodeset(vm->def->numatune,
|
||||
nodemask,
|
||||
&mem_mask) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (vm->def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)
|
||||
mem_mask = virBitmapFormat(nodemask);
|
||||
else
|
||||
mem_mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
|
||||
|
||||
if (!mem_mask)
|
||||
goto cleanup;
|
||||
|
||||
if (virCgroupSetCpusetMems(priv->cgroup, mem_mask) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
if (mem_mask &&
|
||||
virCgroupSetCpusetMems(priv->cgroup, mem_mask) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (vm->def->cpumask ||
|
||||
(vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)) {
|
||||
|
@ -8637,7 +8637,8 @@ qemuDomainSetNumaParamsLive(virDomainObjPtr vm,
|
||||
size_t i = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (vm->def->numatune.memory.mode != VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
|
||||
if (virDomainNumatuneGetMode(vm->def->numatune) !=
|
||||
VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("change of nodeset for running domain "
|
||||
"requires strict numa mode"));
|
||||
@ -8712,6 +8713,8 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
|
||||
virQEMUDriverConfigPtr cfg = NULL;
|
||||
virCapsPtr caps = NULL;
|
||||
qemuDomainObjPrivatePtr priv;
|
||||
virBitmapPtr nodeset = NULL;
|
||||
int mode = -1;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
|
||||
VIR_DOMAIN_AFFECT_CONFIG, -1);
|
||||
@ -8752,65 +8755,47 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
|
||||
virTypedParameterPtr param = ¶ms[i];
|
||||
|
||||
if (STREQ(param->field, VIR_DOMAIN_NUMA_MODE)) {
|
||||
int mode = param->value.i;
|
||||
mode = param->value.i;
|
||||
|
||||
if (mode >= VIR_DOMAIN_NUMATUNE_PLACEMENT_LAST ||
|
||||
mode < VIR_DOMAIN_NUMATUNE_PLACEMENT_DEFAULT)
|
||||
{
|
||||
if (mode < 0 || mode >= VIR_DOMAIN_NUMATUNE_MEM_LAST) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("unsupported numa_mode: '%d'"), mode);
|
||||
_("unsupported numatune mode: '%d'"), mode);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
|
||||
vm->def->numatune.memory.mode != mode) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("can't change numa mode for running domain"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG)
|
||||
persistentDef->numatune.memory.mode = mode;
|
||||
|
||||
} else if (STREQ(param->field, VIR_DOMAIN_NUMA_NODESET)) {
|
||||
virBitmapPtr nodeset = NULL;
|
||||
|
||||
if (virBitmapParse(param->value.s, 0, &nodeset,
|
||||
VIR_DOMAIN_CPUMASK_LEN) < 0) {
|
||||
VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virBitmapIsAllClear(nodeset)) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("Invalid nodeset for numatune"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
|
||||
if (qemuDomainSetNumaParamsLive(vm, caps, nodeset) < 0) {
|
||||
virBitmapFree(nodeset);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* update vm->def here so that dumpxml can read the new
|
||||
* values from vm->def. */
|
||||
virBitmapFree(vm->def->numatune.memory.nodemask);
|
||||
|
||||
vm->def->numatune.memory.placement_mode =
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
vm->def->numatune.memory.nodemask = virBitmapNewCopy(nodeset);
|
||||
}
|
||||
|
||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
||||
virBitmapFree(persistentDef->numatune.memory.nodemask);
|
||||
|
||||
persistentDef->numatune.memory.nodemask = nodeset;
|
||||
persistentDef->numatune.memory.placement_mode =
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC;
|
||||
nodeset = NULL;
|
||||
}
|
||||
virBitmapFree(nodeset);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
|
||||
if (mode != -1 &&
|
||||
virDomainNumatuneGetMode(vm->def->numatune) != mode) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("can't change numatune mode for running domain"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (nodeset &&
|
||||
qemuDomainSetNumaParamsLive(vm, caps, nodeset) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainNumatuneSet(vm->def, -1, mode, nodeset) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
||||
if (!persistentDef->numatune.memory.placement_mode)
|
||||
persistentDef->numatune.memory.placement_mode =
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO;
|
||||
if (virDomainNumatuneSet(persistentDef, -1, mode, nodeset) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
@ -8818,6 +8803,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
virBitmapFree(nodeset);
|
||||
if (vm)
|
||||
virObjectUnlock(vm);
|
||||
virObjectUnref(caps);
|
||||
@ -8886,15 +8872,17 @@ qemuDomainGetNumaParameters(virDomainPtr dom,
|
||||
if (virTypedParameterAssign(param, VIR_DOMAIN_NUMA_MODE,
|
||||
VIR_TYPED_PARAM_INT, 0) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG)
|
||||
param->value.i = persistentDef->numatune.memory.mode;
|
||||
param->value.i = virDomainNumatuneGetMode(persistentDef->numatune);
|
||||
else
|
||||
param->value.i = vm->def->numatune.memory.mode;
|
||||
param->value.i = virDomainNumatuneGetMode(vm->def->numatune);
|
||||
break;
|
||||
|
||||
case 1: /* fill numa nodeset here */
|
||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
||||
nodeset = virBitmapFormat(persistentDef->numatune.memory.nodemask);
|
||||
nodeset = virDomainNumatuneFormatNodeset(persistentDef->numatune,
|
||||
NULL);
|
||||
if (!nodeset)
|
||||
goto cleanup;
|
||||
} else {
|
||||
|
@ -3898,10 +3898,7 @@ int qemuProcessStart(virConnectPtr conn,
|
||||
/* Get the advisory nodeset from numad if 'placement' of
|
||||
* either <vcpu> or <numatune> is 'auto'.
|
||||
*/
|
||||
if ((vm->def->placement_mode ==
|
||||
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
|
||||
(vm->def->numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO)) {
|
||||
if (virDomainDefNeedsPlacementAdvice(vm->def)) {
|
||||
nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus,
|
||||
vm->def->mem.max_balloon);
|
||||
if (!nodeset)
|
||||
@ -3909,8 +3906,7 @@ int qemuProcessStart(virConnectPtr conn,
|
||||
|
||||
VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
|
||||
|
||||
if (virBitmapParse(nodeset, 0, &nodemask,
|
||||
VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||
if (virBitmapParse(nodeset, 0, &nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
hookData.nodemask = nodemask;
|
||||
|
@ -87,11 +87,10 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus ATTRIBUTE_UNUSED,
|
||||
|
||||
#if WITH_NUMACTL
|
||||
int
|
||||
virNumaSetupMemoryPolicy(virDomainNumatune numatune,
|
||||
virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr nodemask)
|
||||
{
|
||||
nodemask_t mask;
|
||||
int mode = -1;
|
||||
int node = -1;
|
||||
int ret = -1;
|
||||
int bit = 0;
|
||||
@ -99,19 +98,9 @@ virNumaSetupMemoryPolicy(virDomainNumatune numatune,
|
||||
int maxnode = 0;
|
||||
virBitmapPtr tmp_nodemask = NULL;
|
||||
|
||||
if (numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) {
|
||||
if (!numatune.memory.nodemask)
|
||||
return 0;
|
||||
VIR_DEBUG("Set NUMA memory policy with specified nodeset");
|
||||
tmp_nodemask = numatune.memory.nodemask;
|
||||
} else if (numatune.memory.placement_mode ==
|
||||
VIR_DOMAIN_NUMATUNE_PLACEMENT_AUTO) {
|
||||
VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
|
||||
tmp_nodemask = nodemask;
|
||||
} else {
|
||||
tmp_nodemask = virDomainNumatuneGetNodeset(numatune, nodemask);
|
||||
if (!tmp_nodemask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (numa_available() < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
@ -134,13 +123,15 @@ virNumaSetupMemoryPolicy(virDomainNumatune numatune,
|
||||
nodemask_set(&mask, bit);
|
||||
}
|
||||
|
||||
mode = numatune.memory.mode;
|
||||
|
||||
if (mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT) {
|
||||
switch (virDomainNumatuneGetMode(numatune)) {
|
||||
case VIR_DOMAIN_NUMATUNE_MEM_STRICT:
|
||||
numa_set_bind_policy(1);
|
||||
numa_set_membind(&mask);
|
||||
numa_set_bind_policy(0);
|
||||
} else if (mode == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) {
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_NUMATUNE_MEM_PREFERRED:
|
||||
{
|
||||
int nnodes = 0;
|
||||
for (i = 0; i < NUMA_NUM_NODES; i++) {
|
||||
if (nodemask_isset(&mask, i)) {
|
||||
@ -158,17 +149,16 @@ virNumaSetupMemoryPolicy(virDomainNumatune numatune,
|
||||
|
||||
numa_set_bind_policy(0);
|
||||
numa_set_preferred(node);
|
||||
} else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
|
||||
numa_set_interleave_mask(&mask);
|
||||
} else {
|
||||
/* XXX: Shouldn't go here, as we already do checking when
|
||||
* parsing domain XML.
|
||||
*/
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
"%s", _("Invalid mode for memory NUMA tuning."));
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE:
|
||||
numa_set_interleave_mask(&mask);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_NUMATUNE_MEM_LAST:
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@ -327,10 +317,10 @@ virNumaGetNodeCPUs(int node,
|
||||
|
||||
#else
|
||||
int
|
||||
virNumaSetupMemoryPolicy(virDomainNumatune numatune,
|
||||
virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr nodemask ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (numatune.memory.nodemask) {
|
||||
if (virDomainNumatuneGetNodeset(numatune, NULL)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("libvirt is compiled without NUMA tuning support"));
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
|
||||
unsigned long long balloon);
|
||||
|
||||
int virNumaSetupMemoryPolicy(virDomainNumatune numatune,
|
||||
int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
|
||||
virBitmapPtr nodemask);
|
||||
|
||||
bool virNumaIsAvailable(void);
|
||||
|
29
tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.xml
Normal file
29
tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<domain type='qemu'>
|
||||
<name>QEMUGuest</name>
|
||||
<uuid>9f4b6512-e73a-4a25-93e8-5307802821ce</uuid>
|
||||
<memory unit='KiB'>65536</memory>
|
||||
<currentMemory unit='KiB'>65536</currentMemory>
|
||||
<vcpu placement='auto'>1</vcpu>
|
||||
<numatune>
|
||||
<memory mode='preferred'/>
|
||||
</numatune>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<cpu>
|
||||
<numa>
|
||||
<cell id='0' cpus='0' memory='65536'/>
|
||||
</numa>
|
||||
</cpu>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/kvm</emulator>
|
||||
<controller type='usb' index='0'/>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<memballoon model='virtio'/>
|
||||
</devices>
|
||||
</domain>
|
@ -0,0 +1,29 @@
|
||||
<domain type='qemu'>
|
||||
<name>QEMUGuest</name>
|
||||
<uuid>9f4b6512-e73a-4a25-93e8-5307802821ce</uuid>
|
||||
<memory unit='KiB'>65536</memory>
|
||||
<currentMemory unit='KiB'>65536</currentMemory>
|
||||
<vcpu placement='auto'>1</vcpu>
|
||||
<numatune>
|
||||
<memory mode='preferred' placement='auto'/>
|
||||
</numatune>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<cpu>
|
||||
<numa>
|
||||
<cell id='0' cpus='0' memory='65536'/>
|
||||
</numa>
|
||||
</cpu>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>destroy</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/bin/kvm</emulator>
|
||||
<controller type='usb' index='0'/>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<memballoon model='virtio'/>
|
||||
</devices>
|
||||
</domain>
|
@ -373,6 +373,8 @@ mymain(void)
|
||||
DO_TEST_DIFFERENT("cpu-numa1");
|
||||
DO_TEST_DIFFERENT("cpu-numa2");
|
||||
|
||||
DO_TEST_DIFFERENT("numatune-auto-prefer");
|
||||
|
||||
virObjectUnref(driver.caps);
|
||||
virObjectUnref(driver.xmlopt);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user