This patch allows passing of a "-mem-path <arg>"
flag to qemu for support of huge page backed
guests. A guest may request this option via
specifying:
<hugepage>on</hugepage>
in its domain definition xml file. The request
for huge page backing will be attempted within
libvirt if the host system has indicated a
hugetlbfs mount point in qemu.conf, for example:
hugepage_mount = "/hugetlbfs"
_and_ the target qemu executable is aware of
the "-mem-path" flag. Otherwise this request
by a guest will result in an error.
This patch does not address setup of the required
host hugetlbfs mount point, verifying the mount
point is correct/usable, nor assure sufficient
free huge pages are available; which are assumed
to be addressed by other means.
Signed-off-by: john cooper <john.cooper(a)redhat.com>
---
diff --git a/src/domain_conf.c b/src/domain_conf.c
index f3e4c6c..04d6911 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -2369,6 +2369,17 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
if (virXPathULong(conn, "string(./currentMemory[1])", ctxt,
&def->memory) < 0)
def->memory = def->maxmem;
+ tmp = virXPathString(conn, "string(./hugepage[1])", ctxt);
+ if (!tmp || STREQ(tmp, "off"))
+ def->hugepage_backed = 0;
+ else if (STREQ(tmp, "on"))
+ def->hugepage_backed = 1;
+ else {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("invalid hugepage mode %s"), tmp);
+ goto error;
+ }
+
if (virXPathULong(conn, "string(./vcpu[1])", ctxt, &def->vcpus) <
0)
def->vcpus = 1;
@@ -3933,6 +3944,8 @@ char *virDomainDefFormat(virConnectPtr conn,
virBufferVSprintf(&buf, " <memory>%lu</memory>\n",
def->maxmem);
virBufferVSprintf(&buf, "
<currentMemory>%lu</currentMemory>\n",
def->memory);
+ if (def->hugepage_backed)
+ virBufferVSprintf(&buf, " <hugepage>%s</hugepage>\n",
"on");
for (n = 0 ; n < def->cpumasklen ; n++)
if (def->cpumask[n] != 1)
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 6e111fa..d6bdcdb 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -481,6 +481,7 @@ struct _virDomainDef {
unsigned long memory;
unsigned long maxmem;
+ unsigned char hugepage_backed;
unsigned long vcpus;
int cpumasklen;
char *cpumask;
diff --git a/src/qemu.conf b/src/qemu.conf
index 3009725..a3387f1 100644
--- a/src/qemu.conf
+++ b/src/qemu.conf
@@ -95,3 +95,10 @@
# The group ID for QEMU processes run by the system instance
#group = "root"
+
+# If provided by the host and this hugetlbfs mount point is
+# configured, a guest may request huge page backing. When this
+# mount point is undefined, huge page backing is disabled.
+
+hugepage_mount = "/hugetlbfs"
+
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 4043d70..632b784 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -218,6 +218,17 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
}
VIR_FREE(group);
+ p = virConfGetValue (conf, "hugepage_mount");
+ CHECK_TYPE ("hugepage_mount", VIR_CONF_STRING);
+ if (p && p->str) {
+ VIR_FREE(driver->hugepage_mount);
+ if (!(driver->hugepage_mount = strdup(p->str))) {
+ virReportOOMError(NULL);
+ virConfFree(conf);
+ return -1;
+ }
+ }
+
virConfFree (conf);
return 0;
}
@@ -500,6 +511,8 @@ static unsigned int qemudComputeCmdFlags(const char *help,
flags |= QEMUD_CMD_FLAG_VGA;
if (strstr(help, "boot=on"))
flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
+ if (strstr(help, "-mem-path"))
+ flags |= QEMUD_CMD_FLAG_MEM_PATH;
if (version >= 9000)
flags |= QEMUD_CMD_FLAG_VNC_COLON;
@@ -1125,6 +1138,15 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("-no-kvm");
ADD_ARG_LIT("-m");
ADD_ARG_LIT(memory);
+ if (def->hugepage_backed) {
+ if (!driver->hugepage_mount || !(qemuCmdFlags & QEMUD_CMD_FLAG_MEM_PATH)) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT,
+ "%s", _("hugepage backing not
supported"));
+ goto error;
+ }
+ ADD_ARG_LIT("-mem-path");
+ ADD_ARG_LIT(driver->hugepage_mount);
+ }
ADD_ARG_LIT("-smp");
ADD_ARG_LIT(vcpus);
diff --git a/src/qemu_conf.h b/src/qemu_conf.h
index fbf2ab9..847597f 100644
--- a/src/qemu_conf.h
+++ b/src/qemu_conf.h
@@ -58,6 +58,7 @@ enum qemud_cmd_flags {
QEMUD_CMD_FLAG_KVM = (1 << 13), /* Whether KVM is compiled in */
QEMUD_CMD_FLAG_DRIVE_FORMAT = (1 << 14), /* Is -drive format= avail */
QEMUD_CMD_FLAG_VGA = (1 << 15), /* Is -vga avail */
+ QEMUD_CMD_FLAG_MEM_PATH = (1 << 16), /* mmap'ped guest backing
supported */
};
/* Main driver state */
@@ -86,6 +87,7 @@ struct qemud_driver {
char *vncListen;
char *vncPassword;
char *vncSASLdir;
+ char *hugepage_mount;
virCapsPtr caps;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 00dc6e5..bdecf5a 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -638,6 +638,7 @@ qemudShutdown(void) {
VIR_FREE(qemu_driver->vncListen);
VIR_FREE(qemu_driver->vncPassword);
VIR_FREE(qemu_driver->vncSASLdir);
+ VIR_FREE(qemu_driver->hugepage_mount);
/* Free domain callback list */
virDomainEventCallbackListFree(qemu_driver->domainEventCallbacks);
--
john.cooper(a)redhat.com