mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-04-26 15:14:42 +00:00
domain: Introduce ./hugepages/page/[@size, @unit, @nodeset]
<memoryBacking> <hugepages> <page size="1" unit="G" nodeset="0-3,5"/> <page size="2" unit="M" nodeset="4"/> </hugepages> </memoryBacking> Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
49baed2b29
commit
136ad49740
@ -617,7 +617,9 @@
|
|||||||
<domain>
|
<domain>
|
||||||
...
|
...
|
||||||
<memoryBacking>
|
<memoryBacking>
|
||||||
<hugepages/>
|
<hugepages>
|
||||||
|
<page size="1" unit="G" nodeset="0-3,5"/>
|
||||||
|
<page size="2" unit="M" nodeset="4"/>
|
||||||
<nosharepages/>
|
<nosharepages/>
|
||||||
<locked/>
|
<locked/>
|
||||||
</memoryBacking>
|
</memoryBacking>
|
||||||
@ -632,7 +634,19 @@
|
|||||||
<dl>
|
<dl>
|
||||||
<dt><code>hugepages</code></dt>
|
<dt><code>hugepages</code></dt>
|
||||||
<dd>This tells the hypervisor that the guest should have its memory
|
<dd>This tells the hypervisor that the guest should have its memory
|
||||||
allocated using hugepages instead of the normal native page size.</dd>
|
allocated using hugepages instead of the normal native page size.
|
||||||
|
<span class='since'>Since 1.2.5</span> it's possible to set hugepages
|
||||||
|
more specifically per numa node. The <code>page</code> element is
|
||||||
|
introduced. It has one compulsory attribute <code>size</code> which
|
||||||
|
specifies which hugepages should be used (especially useful on systems
|
||||||
|
supporting hugepages of different sizes). The default unit for the
|
||||||
|
<code>size</code> attribute is kilobytes (multiplier of 1024). If you
|
||||||
|
want to use different unit, use optional <code>unit</code> attribute.
|
||||||
|
For systems with NUMA, the optional <code>nodeset</code> attribute may
|
||||||
|
come handy as it ties given guest's NUMA nodes to certain hugepage
|
||||||
|
sizes. From the example snippet, one gigabyte hugepages are used for
|
||||||
|
every NUMA node except node number four. For the correct syntax see
|
||||||
|
<a href="#elementsNUMATuning">this</a>.</dd>
|
||||||
<dt><code>nosharepages</code></dt>
|
<dt><code>nosharepages</code></dt>
|
||||||
<dd>Instructs hypervisor to disable shared pages (memory merge, KSM) for
|
<dd>Instructs hypervisor to disable shared pages (memory merge, KSM) for
|
||||||
this domain. <span class="since">Since 1.0.6</span></dd>
|
this domain. <span class="since">Since 1.0.6</span></dd>
|
||||||
|
@ -568,7 +568,24 @@
|
|||||||
<interleave>
|
<interleave>
|
||||||
<optional>
|
<optional>
|
||||||
<element name="hugepages">
|
<element name="hugepages">
|
||||||
<empty/>
|
<zeroOrMore>
|
||||||
|
<element name="page">
|
||||||
|
<attribute name="size">
|
||||||
|
<ref name="unsignedLong"/>
|
||||||
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<attribute name='unit'>
|
||||||
|
<ref name='unit'/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="nodeset">
|
||||||
|
<ref name='cpuset'/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
|
<empty/>
|
||||||
|
</element>
|
||||||
|
</zeroOrMore>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
<optional>
|
<optional>
|
||||||
|
@ -11330,6 +11330,57 @@ virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainHugepagesParseXML(xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
virDomainHugePagePtr hugepage)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
xmlNodePtr oldnode = ctxt->node;
|
||||||
|
unsigned long long bytes, max;
|
||||||
|
char *unit = NULL, *nodeset = NULL;
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
/* On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit
|
||||||
|
* machines, our bound is off_t (2^63). */
|
||||||
|
if (sizeof(unsigned long) < sizeof(long long))
|
||||||
|
max = 1024ull * ULONG_MAX;
|
||||||
|
else
|
||||||
|
max = LLONG_MAX;
|
||||||
|
|
||||||
|
if (virXPathULongLong("string(./@size)", ctxt, &bytes) < 0) {
|
||||||
|
virReportError(VIR_ERR_XML_DETAIL, "%s",
|
||||||
|
_("unable to parse size attribute"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
unit = virXPathString("string(./@unit)", ctxt);
|
||||||
|
|
||||||
|
if (virScaleInteger(&bytes, unit, 1024, max) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(hugepage->size = VIR_DIV_UP(bytes, 1024))) {
|
||||||
|
virReportError(VIR_ERR_XML_DETAIL, "%s",
|
||||||
|
_("hugepage size can't be zero"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nodeset = virXMLPropString(node, "nodeset"))) {
|
||||||
|
if (virBitmapParse(nodeset, 0, &hugepage->nodemask,
|
||||||
|
VIR_DOMAIN_CPUMASK_LEN) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(unit);
|
||||||
|
VIR_FREE(nodeset);
|
||||||
|
ctxt->node = oldnode;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static virDomainResourceDefPtr
|
static virDomainResourceDefPtr
|
||||||
virDomainResourceDefParse(xmlNodePtr node,
|
virDomainResourceDefParse(xmlNodePtr node,
|
||||||
xmlXPathContextPtr ctxt)
|
xmlXPathContextPtr ctxt)
|
||||||
@ -11397,7 +11448,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
{
|
{
|
||||||
xmlNodePtr *nodes = NULL, node = NULL;
|
xmlNodePtr *nodes = NULL, node = NULL;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
size_t i;
|
size_t i, j;
|
||||||
int n;
|
int n;
|
||||||
long id = -1;
|
long id = -1;
|
||||||
virDomainDefPtr def;
|
virDomainDefPtr def;
|
||||||
@ -11547,8 +11598,55 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
def->mem.cur_balloon = def->mem.max_balloon;
|
def->mem.cur_balloon = def->mem.max_balloon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node = virXPathNode("./memoryBacking/hugepages", ctxt)))
|
|
||||||
def->mem.hugepage_backed = true;
|
if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("cannot extract hugepages nodes"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n) {
|
||||||
|
if (VIR_ALLOC_N(def->mem.hugepages, n) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
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))) {
|
||||||
|
if (VIR_ALLOC(def->mem.hugepages) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
def->mem.nhugepages = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt)))
|
if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt)))
|
||||||
def->mem.nosharepages = true;
|
def->mem.nosharepages = true;
|
||||||
@ -11570,7 +11668,6 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
size_t j;
|
|
||||||
if (virDomainBlkioDeviceParseXML(nodes[i],
|
if (virDomainBlkioDeviceParseXML(nodes[i],
|
||||||
&def->blkio.devices[i]) < 0)
|
&def->blkio.devices[i]) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -12509,7 +12606,6 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
|
|
||||||
if (chr->target.port == -1) {
|
if (chr->target.port == -1) {
|
||||||
int maxport = -1;
|
int maxport = -1;
|
||||||
size_t j;
|
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
if (def->parallels[j]->target.port > maxport)
|
if (def->parallels[j]->target.port > maxport)
|
||||||
maxport = def->parallels[j]->target.port;
|
maxport = def->parallels[j]->target.port;
|
||||||
@ -12537,7 +12633,6 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
|
|
||||||
if (chr->target.port == -1) {
|
if (chr->target.port == -1) {
|
||||||
int maxport = -1;
|
int maxport = -1;
|
||||||
size_t j;
|
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
if (def->serials[j]->target.port > maxport)
|
if (def->serials[j]->target.port > maxport)
|
||||||
maxport = def->serials[j]->target.port;
|
maxport = def->serials[j]->target.port;
|
||||||
@ -12595,7 +12690,6 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
|
if (chr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
|
||||||
chr->info.addr.vioserial.port == 0) {
|
chr->info.addr.vioserial.port == 0) {
|
||||||
int maxport = 0;
|
int maxport = 0;
|
||||||
size_t j;
|
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
virDomainChrDefPtr thischr = def->channels[j];
|
virDomainChrDefPtr thischr = def->channels[j];
|
||||||
if (thischr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
|
if (thischr->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL &&
|
||||||
@ -12712,7 +12806,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
if (n && VIR_ALLOC_N(def->videos, n) < 0)
|
if (n && VIR_ALLOC_N(def->videos, n) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
size_t j = def->nvideos;
|
j = def->nvideos;
|
||||||
virDomainVideoDefPtr video = virDomainVideoDefParseXML(nodes[j],
|
virDomainVideoDefPtr video = virDomainVideoDefParseXML(nodes[j],
|
||||||
def,
|
def,
|
||||||
flags);
|
flags);
|
||||||
@ -14138,13 +14232,38 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
|
|||||||
dst->mem.cur_balloon, src->mem.cur_balloon);
|
dst->mem.cur_balloon, src->mem.cur_balloon);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (src->mem.hugepage_backed != dst->mem.hugepage_backed) {
|
if (src->mem.nhugepages != dst->mem.nhugepages) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("Target domain huge page backing %d does not match source %d"),
|
_("Target domain huge pages count %zu does not match source %zu"),
|
||||||
dst->mem.hugepage_backed,
|
dst->mem.nhugepages, src->mem.nhugepages);
|
||||||
src->mem.hugepage_backed);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < src->mem.nhugepages; i++) {
|
||||||
|
virDomainHugePagePtr src_huge = &src->mem.hugepages[i];
|
||||||
|
virDomainHugePagePtr dst_huge = &dst->mem.hugepages[i];
|
||||||
|
|
||||||
|
if (src_huge->size != dst_huge->size) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Target domain huge page size %llu "
|
||||||
|
"does not match source %llu"),
|
||||||
|
dst_huge->size, src_huge->size);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_huge->nodemask && dst_huge->nodemask) {
|
||||||
|
if (!virBitmapEqual(src_huge->nodemask, dst_huge->nodemask)) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("Target huge page nodemask does not match source"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (src_huge->nodemask || dst_huge->nodemask) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("Target huge page nodemask does not match source"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (src->vcpus != dst->vcpus) {
|
if (src->vcpus != dst->vcpus) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
@ -17264,6 +17383,54 @@ virDomainResourceDefFormat(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainHugepagesFormatBuf(virBufferPtr buf,
|
||||||
|
virDomainHugePagePtr hugepage)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
virBufferAsprintf(buf, "<page size='%llu' unit='KiB'",
|
||||||
|
hugepage->size);
|
||||||
|
|
||||||
|
if (hugepage->nodemask) {
|
||||||
|
char *nodeset = NULL;
|
||||||
|
if (!(nodeset = virBitmapFormat(hugepage->nodemask)))
|
||||||
|
goto cleanup;
|
||||||
|
virBufferAsprintf(buf, " nodeset='%s'", nodeset);
|
||||||
|
VIR_FREE(nodeset);
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
virDomainHugepagesFormat(virBufferPtr buf,
|
||||||
|
virDomainHugePagePtr hugepages,
|
||||||
|
size_t nhugepages)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (nhugepages == 1 &&
|
||||||
|
hugepages[0].size == 0) {
|
||||||
|
virBufferAddLit(buf, "<hugepages/>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAddLit(buf, "<hugepages>\n");
|
||||||
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
for (i = 0; i < nhugepages; i++)
|
||||||
|
virDomainHugepagesFormatBuf(buf, &hugepages[i]);
|
||||||
|
|
||||||
|
virBufferAdjustIndent(buf, -2);
|
||||||
|
virBufferAddLit(buf, "</hugepages>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define DUMPXML_FLAGS \
|
#define DUMPXML_FLAGS \
|
||||||
(VIR_DOMAIN_XML_SECURE | \
|
(VIR_DOMAIN_XML_SECURE | \
|
||||||
VIR_DOMAIN_XML_INACTIVE | \
|
VIR_DOMAIN_XML_INACTIVE | \
|
||||||
@ -17460,11 +17627,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
|||||||
virBufferAddLit(buf, "</memtune>\n");
|
virBufferAddLit(buf, "</memtune>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->mem.hugepage_backed || def->mem.nosharepages || def->mem.locked) {
|
if (def->mem.nhugepages || def->mem.nosharepages || def->mem.locked) {
|
||||||
virBufferAddLit(buf, "<memoryBacking>\n");
|
virBufferAddLit(buf, "<memoryBacking>\n");
|
||||||
virBufferAdjustIndent(buf, 2);
|
virBufferAdjustIndent(buf, 2);
|
||||||
if (def->mem.hugepage_backed)
|
if (def->mem.nhugepages)
|
||||||
virBufferAddLit(buf, "<hugepages/>\n");
|
virDomainHugepagesFormat(buf, def->mem.hugepages, def->mem.nhugepages);
|
||||||
if (def->mem.nosharepages)
|
if (def->mem.nosharepages)
|
||||||
virBufferAddLit(buf, "<nosharepages/>\n");
|
virBufferAddLit(buf, "<nosharepages/>\n");
|
||||||
if (def->mem.locked)
|
if (def->mem.locked)
|
||||||
|
@ -1843,6 +1843,14 @@ struct _virDomainResourceDef {
|
|||||||
char *partition;
|
char *partition;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _virDomaiHugePage virDomainHugePage;
|
||||||
|
typedef virDomainHugePage *virDomainHugePagePtr;
|
||||||
|
|
||||||
|
struct _virDomaiHugePage {
|
||||||
|
virBitmapPtr nodemask; /* guest's NUMA node mask */
|
||||||
|
unsigned long long size; /* hugepage size in KiB */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Guest VM main configuration
|
* Guest VM main configuration
|
||||||
*
|
*
|
||||||
@ -1869,7 +1877,10 @@ struct _virDomainDef {
|
|||||||
struct {
|
struct {
|
||||||
unsigned long long max_balloon; /* in kibibytes */
|
unsigned long long max_balloon; /* in kibibytes */
|
||||||
unsigned long long cur_balloon; /* in kibibytes */
|
unsigned long long cur_balloon; /* in kibibytes */
|
||||||
bool hugepage_backed;
|
|
||||||
|
virDomainHugePagePtr hugepages;
|
||||||
|
size_t nhugepages;
|
||||||
|
|
||||||
bool nosharepages;
|
bool nosharepages;
|
||||||
bool locked;
|
bool locked;
|
||||||
int dump_core; /* enum virTristateSwitch */
|
int dump_core; /* enum virTristateSwitch */
|
||||||
|
@ -2023,7 +2023,7 @@ parallelsApplyChanges(virDomainObjPtr dom, virDomainDefPtr new)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old->mem.hugepage_backed != new->mem.hugepage_backed ||
|
if (old->mem.nhugepages != new->mem.nhugepages ||
|
||||||
old->mem.hard_limit != new->mem.hard_limit ||
|
old->mem.hard_limit != new->mem.hard_limit ||
|
||||||
old->mem.soft_limit != new->mem.soft_limit ||
|
old->mem.soft_limit != new->mem.soft_limit ||
|
||||||
old->mem.min_guarantee != new->mem.min_guarantee ||
|
old->mem.min_guarantee != new->mem.min_guarantee ||
|
||||||
|
@ -7383,7 +7383,7 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
virCommandAddArg(cmd, "-m");
|
virCommandAddArg(cmd, "-m");
|
||||||
def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024;
|
def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024;
|
||||||
virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024);
|
virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024);
|
||||||
if (def->mem.hugepage_backed) {
|
if (def->mem.nhugepages) {
|
||||||
char *mem_path;
|
char *mem_path;
|
||||||
|
|
||||||
if (!cfg->nhugetlbfs) {
|
if (!cfg->nhugetlbfs) {
|
||||||
|
@ -3791,7 +3791,7 @@ int qemuProcessStart(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
virDomainAuditSecurityLabel(vm, true);
|
virDomainAuditSecurityLabel(vm, true);
|
||||||
|
|
||||||
if (vm->def->mem.hugepage_backed) {
|
if (vm->def->mem.nhugepages) {
|
||||||
for (i = 0; i < cfg->nhugetlbfs; i++) {
|
for (i = 0; i < cfg->nhugetlbfs; i++) {
|
||||||
char *hugepagePath = qemuGetHugepagePath(&cfg->hugetlbfs[i]);
|
char *hugepagePath = qemuGetHugepagePath(&cfg->hugetlbfs[i]);
|
||||||
|
|
||||||
|
45
tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.xml
Normal file
45
tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.xml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory unit='KiB'>4194304</memory>
|
||||||
|
<currentMemory unit='KiB'>4194304</currentMemory>
|
||||||
|
<memoryBacking>
|
||||||
|
<hugepages>
|
||||||
|
<page size='2048' unit='KiB' nodeset='1'/>
|
||||||
|
<page size='1048576' unit='KiB' nodeset='0,2-3'/>
|
||||||
|
</hugepages>
|
||||||
|
</memoryBacking>
|
||||||
|
<vcpu placement='static'>4</vcpu>
|
||||||
|
<numatune>
|
||||||
|
<memory mode='strict' nodeset='0-3'/>
|
||||||
|
<memnode cellid='3' mode='strict' nodeset='3'/>
|
||||||
|
</numatune>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<cpu>
|
||||||
|
<numa>
|
||||||
|
<cell id='0' cpus='0' memory='1048576'/>
|
||||||
|
<cell id='1' cpus='1' memory='1048576'/>
|
||||||
|
<cell id='2' cpus='2' memory='1048576'/>
|
||||||
|
<cell id='3' cpus='3' memory='1048576'/>
|
||||||
|
</numa>
|
||||||
|
</cpu>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='usb' index='0'/>
|
||||||
|
<controller type='ide' index='0'/>
|
||||||
|
<controller type='pci' index='0' model='pci-root'/>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -197,6 +197,7 @@ mymain(void)
|
|||||||
DO_TEST("hyperv-off");
|
DO_TEST("hyperv-off");
|
||||||
|
|
||||||
DO_TEST("hugepages");
|
DO_TEST("hugepages");
|
||||||
|
DO_TEST("hugepages-pages");
|
||||||
DO_TEST("nosharepages");
|
DO_TEST("nosharepages");
|
||||||
DO_TEST("disk-aio");
|
DO_TEST("disk-aio");
|
||||||
DO_TEST("disk-cdrom");
|
DO_TEST("disk-cdrom");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user