Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 444

kvm-83-164.el5_5.9.src.rpm

From a0399a7af55acdecdac3185b39b26bef9b67f805 Mon Sep 17 00:00:00 2001
From: john cooper <john.cooper@redhat.com>
Date: Tue, 10 Feb 2009 11:39:49 -0200
Subject: [PATCH 63/70] kvm: qemu: preallocate -mem-path memory by default

Attached is a patch to qemu which adds an option to preallocate of huge
pages at startup time, making it the default.

The motivation for this arose from odd behavior seen in qemu when access
to huge page backed phys_mem failed during startup (eg: loading the
bios), and during runtime where a guest will terminate via signal if a
free hpage isn't available to satisfy a guest page fault.

This is believed to be an interim solution until proper huge page
support is available from within the kernel+kvm, ideally allowing
fallback to 4K pages on a dynamic basis and ultimately allowing huge
pages faults to reclaim huge pages from other users in the system.

[ehabkost: solved trivial conflicts on vl.c]

Conflicts:

	qemu/vl.c

Signed-off-by: john cooper <john.cooper@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Upstream-status: applied(kvm/master)
Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
---
 qemu/vl.c |   38 ++++++++++++++++++++++++++++++++++----
 1 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/qemu/vl.c b/qemu/vl.c
index be94ce4..187d39e 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -248,6 +248,9 @@ int semihosting_enabled = 0;
 int time_drift_fix = 0;
 unsigned int kvm_shadow_memory = 0;
 const char *mem_path = NULL;
+#ifdef MAP_POPULATE
+int mem_prealloc = 1;	/* force preallocation of physical target memory */
+#endif
 int hpagesize = 0;
 const char *cpu_vendor_string;
 #ifdef TARGET_ARM
@@ -4209,7 +4212,12 @@ static void help(int exitcode)
 #endif
            "-tdf            inject timer interrupts that got lost\n"
            "-kvm-shadow-memory megs set the amount of shadow pages to be allocated\n"
-           "-mem-path       set the path to hugetlbfs/tmpfs mounted directory, also enables allocation of guest memory with huge pages\n"
+           "-mem-path       set the path to hugetlbfs/tmpfs mounted directory, also\n"
+           "                enables allocation of guest memory with huge pages\n"
+#ifdef MAP_POPULATE
+           "-mem-prealloc   toggles preallocation of -mem-path backed physical memory\n"
+           "                at startup.  Default is enabled.\n"
+#endif
 	   "-option-rom rom load a file, rom, into the option ROM space\n"
 #ifdef TARGET_SPARC
            "-prom-env variable=value  set OpenBIOS nvram variables\n"
@@ -4352,6 +4360,9 @@ enum {
     QEMU_OPTION_spice,
     QEMU_OPTION_spice_help,
 #endif
+#ifdef MAP_POPULATE
+    QEMU_OPTION_mem_prealloc,
+#endif
 };
 
 typedef struct QEMUOption {
@@ -4496,6 +4507,9 @@ static const QEMUOption qemu_options[] = {
     { "spice", HAS_ARG, QEMU_OPTION_spice },
     { "spice-help", 0, QEMU_OPTION_spice_help },
 #endif
+#ifdef MAP_POPULATE
+    { "mem-prealloc", 0, QEMU_OPTION_mem_prealloc },
+#endif
     { NULL },
 };
 
@@ -4783,6 +4797,9 @@ void *alloc_mem_area(size_t memory, unsigned long *len, const char *path)
     char *filename;
     void *area;
     int fd;
+#ifdef MAP_POPULATE
+    int flags;
+#endif
 
     if (asprintf(&filename, "%s/kvm.XXXXXX", path) == -1)
 	return NULL;
@@ -4810,13 +4827,21 @@ void *alloc_mem_area(size_t memory, unsigned long *len, const char *path)
      */
     ftruncate(fd, memory);
 
+#ifdef MAP_POPULATE
+    /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
+     * MAP_PRIVATE is requested.  For mem_prealloc we mmap as MAP_SHARED
+     * to sidestep this quirk.
+     */
+    flags = mem_prealloc ? MAP_POPULATE|MAP_SHARED : MAP_PRIVATE;
+    area = mmap(0, memory, PROT_READ|PROT_WRITE, flags, fd, 0);
+#else
     area = mmap(0, memory, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+#endif
     if (area == MAP_FAILED) {
-	perror("mmap");
+	perror("alloc_mem_area: can't mmap hugetlbfs pages");
 	close(fd);
-	return NULL;
+	return (NULL);
     }
-
     *len = memory;
     return area;
 }
@@ -5621,6 +5646,11 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_mempath:
 		mem_path = optarg;
 		break;
+#ifdef MAP_POPULATE
+            case QEMU_OPTION_mem_prealloc:
+		mem_prealloc = !mem_prealloc;
+		break;
+#endif
             case QEMU_OPTION_name:
                 qemu_name = optarg;
                 break;
-- 
1.6.1