mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
NUMA: cleanup for numa related codes
Intend to reduce the redundant code,use virNumaSetupMemoryPolicy to replace virLXCControllerSetupNUMAPolicy and qemuProcessInitNumaMemoryPolicy. This patch also moves the numa related codes to the file virnuma.c and virnuma.h Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
This commit is contained in:
parent
4755e863d1
commit
45e9d27ad8
@ -690,11 +690,6 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
|
|||||||
"paravirt",
|
"paravirt",
|
||||||
"smpsafe");
|
"smpsafe");
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
|
|
||||||
"strict",
|
|
||||||
"preferred",
|
|
||||||
"interleave");
|
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST,
|
VIR_ENUM_IMPL(virDomainStartupPolicy, VIR_DOMAIN_STARTUP_POLICY_LAST,
|
||||||
"default",
|
"default",
|
||||||
"mandatory",
|
"mandatory",
|
||||||
@ -709,12 +704,6 @@ VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST,
|
|||||||
"closed",
|
"closed",
|
||||||
"open");
|
"open");
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainNumatuneMemPlacementMode,
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST,
|
|
||||||
"default",
|
|
||||||
"static",
|
|
||||||
"auto");
|
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainRNGModel,
|
VIR_ENUM_IMPL(virDomainRNGModel,
|
||||||
VIR_DOMAIN_RNG_MODEL_LAST,
|
VIR_DOMAIN_RNG_MODEL_LAST,
|
||||||
"virtio");
|
"virtio");
|
||||||
@ -9852,7 +9841,7 @@ virDomainDefParseXML(virCapsPtr caps,
|
|||||||
int placement_mode = 0;
|
int placement_mode = 0;
|
||||||
if (placement) {
|
if (placement) {
|
||||||
if ((placement_mode =
|
if ((placement_mode =
|
||||||
virDomainNumatuneMemPlacementModeTypeFromString(placement)) < 0) {
|
virNumaTuneMemPlacementModeTypeFromString(placement)) < 0) {
|
||||||
virReportError(VIR_ERR_XML_ERROR,
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
_("Unsupported memory placement "
|
_("Unsupported memory placement "
|
||||||
"mode '%s'"), placement);
|
"mode '%s'"), placement);
|
||||||
@ -9862,18 +9851,18 @@ virDomainDefParseXML(virCapsPtr caps,
|
|||||||
VIR_FREE(placement);
|
VIR_FREE(placement);
|
||||||
} else if (def->numatune.memory.nodemask) {
|
} else if (def->numatune.memory.nodemask) {
|
||||||
/* Defaults to "static" if nodeset is specified. */
|
/* Defaults to "static" if nodeset is specified. */
|
||||||
placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
|
placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
|
||||||
} else {
|
} else {
|
||||||
/* Defaults to "placement" of <vcpu> if nodeset is
|
/* Defaults to "placement" of <vcpu> if nodeset is
|
||||||
* not specified.
|
* not specified.
|
||||||
*/
|
*/
|
||||||
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
|
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC)
|
||||||
placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
|
placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
|
||||||
else
|
else
|
||||||
placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
|
placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC &&
|
if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC &&
|
||||||
!def->numatune.memory.nodemask) {
|
!def->numatune.memory.nodemask) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("nodeset for NUMA memory tuning must be set "
|
_("nodeset for NUMA memory tuning must be set "
|
||||||
@ -9882,13 +9871,13 @@ virDomainDefParseXML(virCapsPtr caps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore 'nodeset' if 'placement' is 'auto' finally */
|
/* Ignore 'nodeset' if 'placement' is 'auto' finally */
|
||||||
if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
|
if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
|
||||||
virBitmapFree(def->numatune.memory.nodemask);
|
virBitmapFree(def->numatune.memory.nodemask);
|
||||||
|
|
||||||
/* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
|
/* Copy 'placement' of <numatune> to <vcpu> if its 'placement'
|
||||||
* is not specified and 'placement' of <numatune> is specified.
|
* is not specified and 'placement' of <numatune> is specified.
|
||||||
*/
|
*/
|
||||||
if (placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO &&
|
if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO &&
|
||||||
!def->cpumask)
|
!def->cpumask)
|
||||||
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
|
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
|
||||||
|
|
||||||
@ -9907,7 +9896,7 @@ virDomainDefParseXML(virCapsPtr caps,
|
|||||||
* and 'placement' of <vcpu> is 'auto'.
|
* and 'placement' of <vcpu> is 'auto'.
|
||||||
*/
|
*/
|
||||||
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
|
if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
|
||||||
def->numatune.memory.placement_mode = VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
|
def->numatune.memory.placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
|
||||||
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -14818,7 +14807,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
|||||||
virBufferAsprintf(buf, " <memory mode='%s' ", mode);
|
virBufferAsprintf(buf, " <memory mode='%s' ", mode);
|
||||||
|
|
||||||
if (def->numatune.memory.placement_mode ==
|
if (def->numatune.memory.placement_mode ==
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC) {
|
||||||
nodemask = virBitmapFormat(def->numatune.memory.nodemask);
|
nodemask = virBitmapFormat(def->numatune.memory.nodemask);
|
||||||
if (nodemask == NULL) {
|
if (nodemask == NULL) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
@ -14829,7 +14818,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
|||||||
virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
|
virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
|
||||||
VIR_FREE(nodemask);
|
VIR_FREE(nodemask);
|
||||||
} else if (def->numatune.memory.placement_mode) {
|
} else if (def->numatune.memory.placement_mode) {
|
||||||
placement = virDomainNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
|
placement = virNumaTuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
|
||||||
virBufferAsprintf(buf, "placement='%s'/>\n", placement);
|
virBufferAsprintf(buf, "placement='%s'/>\n", placement);
|
||||||
}
|
}
|
||||||
virBufferAddLit(buf, " </numatune>\n");
|
virBufferAddLit(buf, " </numatune>\n");
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
# include "device_conf.h"
|
# include "device_conf.h"
|
||||||
# include "virbitmap.h"
|
# include "virbitmap.h"
|
||||||
# include "virstoragefile.h"
|
# include "virstoragefile.h"
|
||||||
|
# include "virnuma.h"
|
||||||
|
|
||||||
/* forward declarations of all device types, required by
|
/* forward declarations of all device types, required by
|
||||||
* virDomainDeviceDef
|
* virDomainDeviceDef
|
||||||
@ -1605,14 +1606,6 @@ enum virDomainCpuPlacementMode {
|
|||||||
VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST
|
VIR_DOMAIN_CPU_PLACEMENT_MODE_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
enum virDomainNumatuneMemPlacementMode {
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC,
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO,
|
|
||||||
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef;
|
typedef struct _virDomainTimerCatchupDef virDomainTimerCatchupDef;
|
||||||
typedef virDomainTimerCatchupDef *virDomainTimerCatchupDefPtr;
|
typedef virDomainTimerCatchupDef *virDomainTimerCatchupDefPtr;
|
||||||
struct _virDomainTimerCatchupDef {
|
struct _virDomainTimerCatchupDef {
|
||||||
@ -1701,18 +1694,6 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
|
|||||||
int nvcpupin,
|
int nvcpupin,
|
||||||
int vcpu);
|
int vcpu);
|
||||||
|
|
||||||
typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
|
|
||||||
typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
|
|
||||||
struct _virDomainNumatuneDef {
|
|
||||||
struct {
|
|
||||||
virBitmapPtr nodemask;
|
|
||||||
int mode;
|
|
||||||
int placement_mode; /* enum virDomainNumatuneMemPlacementMode */
|
|
||||||
} memory;
|
|
||||||
|
|
||||||
/* Future NUMA tuning related stuff should go here. */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
|
typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
|
||||||
typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
|
typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
|
||||||
struct _virBlkioDeviceWeight {
|
struct _virBlkioDeviceWeight {
|
||||||
@ -1802,7 +1783,7 @@ struct _virDomainDef {
|
|||||||
virDomainVcpuPinDefPtr emulatorpin;
|
virDomainVcpuPinDefPtr emulatorpin;
|
||||||
} cputune;
|
} cputune;
|
||||||
|
|
||||||
virDomainNumatuneDef numatune;
|
virNumaTuneDef numatune;
|
||||||
|
|
||||||
/* These 3 are based on virDomainLifeCycleAction enum flags */
|
/* These 3 are based on virDomainLifeCycleAction enum flags */
|
||||||
int onReboot;
|
int onReboot;
|
||||||
@ -2397,8 +2378,6 @@ VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
|
|||||||
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
|
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
|
||||||
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
|
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
|
||||||
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
|
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
|
||||||
VIR_ENUM_DECL(virDomainNumatuneMemMode)
|
|
||||||
VIR_ENUM_DECL(virDomainNumatuneMemPlacementMode)
|
|
||||||
VIR_ENUM_DECL(virDomainHyperv)
|
VIR_ENUM_DECL(virDomainHyperv)
|
||||||
VIR_ENUM_DECL(virDomainRNGModel)
|
VIR_ENUM_DECL(virDomainRNGModel)
|
||||||
VIR_ENUM_DECL(virDomainRNGBackend)
|
VIR_ENUM_DECL(virDomainRNGBackend)
|
||||||
|
@ -252,10 +252,6 @@ virDomainNetRemove;
|
|||||||
virDomainNetTypeToString;
|
virDomainNetTypeToString;
|
||||||
virDomainNostateReasonTypeFromString;
|
virDomainNostateReasonTypeFromString;
|
||||||
virDomainNostateReasonTypeToString;
|
virDomainNostateReasonTypeToString;
|
||||||
virDomainNumatuneMemModeTypeFromString;
|
|
||||||
virDomainNumatuneMemModeTypeToString;
|
|
||||||
virDomainNumatuneMemPlacementModeTypeFromString;
|
|
||||||
virDomainNumatuneMemPlacementModeTypeToString;
|
|
||||||
virDomainObjAssignDef;
|
virDomainObjAssignDef;
|
||||||
virDomainObjCopyPersistentDef;
|
virDomainObjCopyPersistentDef;
|
||||||
virDomainObjGetPersistentDef;
|
virDomainObjGetPersistentDef;
|
||||||
@ -1557,7 +1553,12 @@ virNodeSuspendGetTargetMask;
|
|||||||
|
|
||||||
|
|
||||||
# util/virnuma.h
|
# util/virnuma.h
|
||||||
|
virDomainNumatuneMemModeTypeFromString;
|
||||||
|
virDomainNumatuneMemModeTypeToString;
|
||||||
virNumaGetAutoPlacementAdvice;
|
virNumaGetAutoPlacementAdvice;
|
||||||
|
virNumaSetupMemoryPolicy;
|
||||||
|
virNumaTuneMemPlacementModeTypeFromString;
|
||||||
|
virNumaTuneMemPlacementModeTypeToString;
|
||||||
|
|
||||||
# util/virobject.h
|
# util/virobject.h
|
||||||
virClassForObject;
|
virClassForObject;
|
||||||
|
@ -46,11 +46,6 @@
|
|||||||
# include <cap-ng.h>
|
# include <cap-ng.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WITH_NUMACTL
|
|
||||||
# define NUMA_VERSION1_COMPATIBILITY 1
|
|
||||||
# include <numa.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virutil.h"
|
#include "virutil.h"
|
||||||
@ -469,113 +464,6 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_NUMACTL
|
|
||||||
static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
|
|
||||||
virBitmapPtr nodemask)
|
|
||||||
{
|
|
||||||
nodemask_t mask;
|
|
||||||
int mode = -1;
|
|
||||||
int node = -1;
|
|
||||||
int ret = -1;
|
|
||||||
int i = 0;
|
|
||||||
int maxnode = 0;
|
|
||||||
bool warned = false;
|
|
||||||
virDomainNumatuneDef numatune = ctrl->def->numatune;
|
|
||||||
virBitmapPtr tmp_nodemask = NULL;
|
|
||||||
|
|
||||||
if (numatune.memory.placement_mode ==
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_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_MEM_PLACEMENT_MODE_AUTO) {
|
|
||||||
VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
|
|
||||||
tmp_nodemask = nodemask;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
VIR_DEBUG("Setting NUMA memory policy");
|
|
||||||
|
|
||||||
if (numa_available() < 0) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
"%s", _("Host kernel is not aware of NUMA."));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxnode = numa_max_node() + 1;
|
|
||||||
|
|
||||||
/* Convert nodemask to NUMA bitmask. */
|
|
||||||
nodemask_zero(&mask);
|
|
||||||
i = -1;
|
|
||||||
while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
|
|
||||||
if (i > NUMA_NUM_NODES) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
_("Host cannot support NUMA node %d"), i);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (i > maxnode && !warned) {
|
|
||||||
VIR_WARN("nodeset is out of range, there is only %d NUMA "
|
|
||||||
"nodes on host", maxnode);
|
|
||||||
warned = true;
|
|
||||||
}
|
|
||||||
nodemask_set(&mask, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = ctrl->def->numatune.memory.mode;
|
|
||||||
|
|
||||||
if (mode == 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) {
|
|
||||||
int nnodes = 0;
|
|
||||||
for (i = 0; i < NUMA_NUM_NODES; i++) {
|
|
||||||
if (nodemask_isset(&mask, i)) {
|
|
||||||
node = i;
|
|
||||||
nnodes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nnodes != 1) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
"%s", _("NUMA memory tuning in 'preferred' mode "
|
|
||||||
"only supports single node"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
numa_set_bind_policy(0);
|
|
||||||
numa_set_preferred(node);
|
|
||||||
} else if (mode == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) {
|
|
||||||
numa_set_interleave_mask(&mask);
|
|
||||||
} else {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
_("Unable to set NUMA policy %s"),
|
|
||||||
virDomainNumatuneMemModeTypeToString(mode));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int virLXCControllerSetupNUMAPolicy(virLXCControllerPtr ctrl,
|
|
||||||
virBitmapPtr nodemask ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
if (ctrl->def->numatune.memory.nodemask) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
||||||
_("NUMA policy is not available on this platform"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To be run while still single threaded
|
* To be run while still single threaded
|
||||||
@ -638,7 +526,7 @@ static int virLXCControllerGetNumadAdvice(virLXCControllerPtr ctrl,
|
|||||||
if ((ctrl->def->placement_mode ==
|
if ((ctrl->def->placement_mode ==
|
||||||
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
|
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
|
||||||
(ctrl->def->numatune.memory.placement_mode ==
|
(ctrl->def->numatune.memory.placement_mode ==
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) {
|
||||||
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
|
nodeset = virNumaGetAutoPlacementAdvice(ctrl->def->vcpus,
|
||||||
ctrl->def->mem.cur_balloon);
|
ctrl->def->mem.cur_balloon);
|
||||||
if (!nodeset)
|
if (!nodeset)
|
||||||
@ -675,7 +563,7 @@ static int virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
|
if (virLXCControllerGetNumadAdvice(ctrl, &nodemask) < 0 ||
|
||||||
virLXCControllerSetupNUMAPolicy(ctrl, nodemask) < 0)
|
virNumaSetupMemoryPolicy(ctrl->def->numatune, nodemask) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virLXCControllerSetupCpuAffinity(ctrl) < 0)
|
if (virLXCControllerSetupCpuAffinity(ctrl) < 0)
|
||||||
|
@ -423,12 +423,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
|
|||||||
|
|
||||||
if ((vm->def->numatune.memory.nodemask ||
|
if ((vm->def->numatune.memory.nodemask ||
|
||||||
(vm->def->numatune.memory.placement_mode ==
|
(vm->def->numatune.memory.placement_mode ==
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) &&
|
||||||
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
|
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
|
||||||
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
|
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
|
||||||
char *mask = NULL;
|
char *mask = NULL;
|
||||||
if (vm->def->numatune.memory.placement_mode ==
|
if (vm->def->numatune.memory.placement_mode ==
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
|
||||||
mask = virBitmapFormat(nodemask);
|
mask = virBitmapFormat(nodemask);
|
||||||
else
|
else
|
||||||
mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
|
mask = virBitmapFormat(vm->def->numatune.memory.nodemask);
|
||||||
|
@ -7648,7 +7648,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
|
|||||||
virBitmapFree(vm->def->numatune.memory.nodemask);
|
virBitmapFree(vm->def->numatune.memory.nodemask);
|
||||||
|
|
||||||
vm->def->numatune.memory.placement_mode =
|
vm->def->numatune.memory.placement_mode =
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
|
||||||
vm->def->numatune.memory.nodemask = virBitmapNewCopy(nodeset);
|
vm->def->numatune.memory.nodemask = virBitmapNewCopy(nodeset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7657,7 +7657,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
|
|||||||
|
|
||||||
persistentDef->numatune.memory.nodemask = nodeset;
|
persistentDef->numatune.memory.nodemask = nodeset;
|
||||||
persistentDef->numatune.memory.placement_mode =
|
persistentDef->numatune.memory.placement_mode =
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC;
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC;
|
||||||
nodeset = NULL;
|
nodeset = NULL;
|
||||||
}
|
}
|
||||||
virBitmapFree(nodeset);
|
virBitmapFree(nodeset);
|
||||||
@ -7667,7 +7667,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom,
|
|||||||
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
|
||||||
if (!persistentDef->numatune.memory.placement_mode)
|
if (!persistentDef->numatune.memory.placement_mode)
|
||||||
persistentDef->numatune.memory.placement_mode =
|
persistentDef->numatune.memory.placement_mode =
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO;
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO;
|
||||||
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
|
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,6 @@
|
|||||||
#include "qemu_bridge_filter.h"
|
#include "qemu_bridge_filter.h"
|
||||||
#include "qemu_migration.h"
|
#include "qemu_migration.h"
|
||||||
|
|
||||||
#if WITH_NUMACTL
|
|
||||||
# define NUMA_VERSION1_COMPATIBILITY 1
|
|
||||||
# include <numa.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "datatypes.h"
|
#include "datatypes.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
@ -1791,120 +1786,6 @@ qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set NUMA memory policy for qemu process, to be run between
|
|
||||||
* fork/exec of QEMU only.
|
|
||||||
*/
|
|
||||||
#if WITH_NUMACTL
|
|
||||||
static int
|
|
||||||
qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
|
|
||||||
virBitmapPtr nodemask)
|
|
||||||
{
|
|
||||||
nodemask_t mask;
|
|
||||||
int mode = -1;
|
|
||||||
int node = -1;
|
|
||||||
int ret = -1;
|
|
||||||
int i = 0;
|
|
||||||
int maxnode = 0;
|
|
||||||
bool warned = false;
|
|
||||||
virDomainNumatuneDef numatune = vm->def->numatune;
|
|
||||||
virBitmapPtr tmp_nodemask = NULL;
|
|
||||||
|
|
||||||
if (numatune.memory.placement_mode ==
|
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_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_MEM_PLACEMENT_MODE_AUTO) {
|
|
||||||
VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
|
|
||||||
tmp_nodemask = nodemask;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numa_available() < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"%s", _("Host kernel is not aware of NUMA."));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxnode = numa_max_node() + 1;
|
|
||||||
/* Convert nodemask to NUMA bitmask. */
|
|
||||||
nodemask_zero(&mask);
|
|
||||||
i = -1;
|
|
||||||
while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
|
|
||||||
if (i > NUMA_NUM_NODES) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Host cannot support NUMA node %d"), i);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (i > maxnode && !warned) {
|
|
||||||
VIR_WARN("nodeset is out of range, there is only %d NUMA "
|
|
||||||
"nodes on host", maxnode);
|
|
||||||
warned = true;
|
|
||||||
}
|
|
||||||
nodemask_set(&mask, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
mode = numatune.memory.mode;
|
|
||||||
|
|
||||||
if (mode == 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) {
|
|
||||||
int nnodes = 0;
|
|
||||||
for (i = 0; i < NUMA_NUM_NODES; i++) {
|
|
||||||
if (nodemask_isset(&mask, i)) {
|
|
||||||
node = i;
|
|
||||||
nnodes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nnodes != 1) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"%s", _("NUMA memory tuning in 'preferred' mode "
|
|
||||||
"only supports single node"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static int
|
|
||||||
qemuProcessInitNumaMemoryPolicy(virDomainObjPtr vm,
|
|
||||||
virBitmapPtr nodemask ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
if (vm->def->numatune.memory.nodemask) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("libvirt is compiled without NUMA tuning support"));
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper to prepare cpumap for affinity setting, convert
|
/* Helper to prepare cpumap for affinity setting, convert
|
||||||
* NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
|
* NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
|
||||||
* just return a new allocated bitmap.
|
* just return a new allocated bitmap.
|
||||||
@ -2654,7 +2535,7 @@ static int qemuProcessHook(void *data)
|
|||||||
qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
|
qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
|
if (virNumaSetupMemoryPolicy(h->vm->def->numatune, h->nodemask) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -3608,7 +3489,7 @@ int qemuProcessStart(virConnectPtr conn,
|
|||||||
if ((vm->def->placement_mode ==
|
if ((vm->def->placement_mode ==
|
||||||
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
|
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
|
||||||
(vm->def->numatune.memory.placement_mode ==
|
(vm->def->numatune.memory.placement_mode ==
|
||||||
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) {
|
||||||
nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus,
|
nodeset = virNumaGetAutoPlacementAdvice(vm->def->vcpus,
|
||||||
vm->def->mem.cur_balloon);
|
vm->def->mem.cur_balloon);
|
||||||
if (!nodeset)
|
if (!nodeset)
|
||||||
|
@ -21,12 +21,30 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#if WITH_NUMACTL
|
||||||
|
# define NUMA_VERSION1_COMPATIBILITY 1
|
||||||
|
# include <numa.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "virnuma.h"
|
#include "virnuma.h"
|
||||||
#include "vircommand.h"
|
#include "vircommand.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainNumatuneMemMode,
|
||||||
|
VIR_DOMAIN_NUMATUNE_MEM_LAST,
|
||||||
|
"strict",
|
||||||
|
"preferred",
|
||||||
|
"interleave");
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virNumaTuneMemPlacementMode,
|
||||||
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_LAST,
|
||||||
|
"default",
|
||||||
|
"static",
|
||||||
|
"auto");
|
||||||
|
|
||||||
#if HAVE_NUMAD
|
#if HAVE_NUMAD
|
||||||
char *
|
char *
|
||||||
virNumaGetAutoPlacementAdvice(unsigned short vcpus,
|
virNumaGetAutoPlacementAdvice(unsigned short vcpus,
|
||||||
@ -59,3 +77,111 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus ATTRIBUTE_UNUSED,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if WITH_NUMACTL
|
||||||
|
int
|
||||||
|
virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
|
||||||
|
virBitmapPtr nodemask)
|
||||||
|
{
|
||||||
|
nodemask_t mask;
|
||||||
|
int mode = -1;
|
||||||
|
int node = -1;
|
||||||
|
int ret = -1;
|
||||||
|
int i = 0;
|
||||||
|
int maxnode = 0;
|
||||||
|
bool warned = false;
|
||||||
|
virBitmapPtr tmp_nodemask = NULL;
|
||||||
|
|
||||||
|
if (numatune.memory.placement_mode ==
|
||||||
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_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_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) {
|
||||||
|
VIR_DEBUG("Set NUMA memory policy with advisory nodeset from numad");
|
||||||
|
tmp_nodemask = nodemask;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numa_available() < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("Host kernel is not aware of NUMA."));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxnode = numa_max_node() + 1;
|
||||||
|
/* Convert nodemask to NUMA bitmask. */
|
||||||
|
nodemask_zero(&mask);
|
||||||
|
i = -1;
|
||||||
|
while ((i = virBitmapNextSetBit(tmp_nodemask, i)) >= 0) {
|
||||||
|
if (i > NUMA_NUM_NODES) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Host cannot support NUMA node %d"), i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (i > maxnode && !warned) {
|
||||||
|
VIR_WARN("nodeset is out of range, there is only %d NUMA "
|
||||||
|
"nodes on host", maxnode);
|
||||||
|
warned = true;
|
||||||
|
}
|
||||||
|
nodemask_set(&mask, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = numatune.memory.mode;
|
||||||
|
|
||||||
|
if (mode == 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) {
|
||||||
|
int nnodes = 0;
|
||||||
|
for (i = 0; i < NUMA_NUM_NODES; i++) {
|
||||||
|
if (nodemask_isset(&mask, i)) {
|
||||||
|
node = i;
|
||||||
|
nnodes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nnodes != 1) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"%s", _("NUMA memory tuning in 'preferred' mode "
|
||||||
|
"only supports single node"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int
|
||||||
|
virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
|
||||||
|
virBitmapPtr nodemask ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (numatune.memory.nodemask) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("libvirt is compiled without NUMA tuning support"));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -22,7 +22,37 @@
|
|||||||
#ifndef __VIR_NUMA_H__
|
#ifndef __VIR_NUMA_H__
|
||||||
# define __VIR_NUMA_H__
|
# define __VIR_NUMA_H__
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
# include "virbitmap.h"
|
||||||
|
# include "virutil.h"
|
||||||
|
|
||||||
|
enum virNumaTuneMemPlacementMode {
|
||||||
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_DEFAULT = 0,
|
||||||
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC,
|
||||||
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO,
|
||||||
|
|
||||||
|
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_LAST
|
||||||
|
};
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(virNumaTuneMemPlacementMode)
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(virDomainNumatuneMemMode)
|
||||||
|
|
||||||
|
typedef struct _virNumaTuneDef virNumaTuneDef;
|
||||||
|
typedef virNumaTuneDef *virNumaTuneDefPtr;
|
||||||
|
struct _virNumaTuneDef {
|
||||||
|
struct {
|
||||||
|
virBitmapPtr nodemask;
|
||||||
|
int mode;
|
||||||
|
int placement_mode; /* enum virNumaTuneMemPlacementMode */
|
||||||
|
} memory;
|
||||||
|
|
||||||
|
/* Future NUMA tuning related stuff should go here. */
|
||||||
|
};
|
||||||
|
|
||||||
char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
|
char *virNumaGetAutoPlacementAdvice(unsigned short vcups,
|
||||||
unsigned long long balloon);
|
unsigned long long balloon);
|
||||||
|
|
||||||
|
int virNumaSetupMemoryPolicy(virNumaTuneDef numatune,
|
||||||
|
virBitmapPtr nodemask);
|
||||||
#endif /* __VIR_NUMA_H__ */
|
#endif /* __VIR_NUMA_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user