[libvirt] [PATCH] Add huge page support to libvirt..

john cooper john.cooper at redhat.com
Thu Jul 23 01:25:02 UTC 2009


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 at 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 at redhat.com




More information about the libvir-list mailing list