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