[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] qemu: mempath: prefault pages manually (v4)
From: |
Marcelo Tosatti |
Subject: |
[Qemu-devel] qemu: mempath: prefault pages manually (v4) |
Date: |
Mon, 28 Oct 2013 18:51:46 -0200 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
v4: s/fail/failed/ (Peter Maydell)
---
MAP_POPULATE mmap flag does not cause mmap to fail if allocation of the
entire area is not performed. HugeTLBfs performs reservation of pages
on a global basis: any further restriction to the reserved memory such
as cpusets placement or numa node policy is performed at fault time
only.
Manually fault in pages at allocation time. This allows memory
restrictions to be applied before guest initialization.
Signed-off-by: Marcelo Tosatti <address@hidden>
diff --git a/exec.c b/exec.c
index 2e31ffc..e6bdcec 100644
--- a/exec.c
+++ b/exec.c
@@ -902,6 +902,13 @@ static long gethugepagesize(const char *path)
return fs.f_bsize;
}
+static sigjmp_buf sigjump;
+
+static void sigbus_handler(int signal)
+{
+ siglongjmp(sigjump, 1);
+}
+
static void *file_ram_alloc(RAMBlock *block,
ram_addr_t memory,
const char *path)
@@ -911,9 +918,6 @@ static void *file_ram_alloc(RAMBlock *block,
char *c;
void *area;
int fd;
-#ifdef MAP_POPULATE
- int flags;
-#endif
unsigned long hpagesize;
hpagesize = gethugepagesize(path);
@@ -961,21 +965,52 @@ static void *file_ram_alloc(RAMBlock *block,
if (ftruncate(fd, memory))
perror("ftruncate");
-#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("file_ram_alloc: can't mmap RAM pages");
close(fd);
return (NULL);
}
+
+ if (mem_prealloc) {
+ int ret, i;
+ struct sigaction act, oldact;
+ sigset_t set, oldset;
+
+ memset(&act, 0, sizeof(act));
+ act.sa_handler = &sigbus_handler;
+ act.sa_flags = 0;
+
+ ret = sigaction(SIGBUS, &act, &oldact);
+ if (ret) {
+ perror("file_ram_alloc: failed to install signal handler");
+ exit(1);
+ }
+
+ /* unblock SIGBUS */
+ sigemptyset(&set);
+ sigaddset(&set, SIGBUS);
+ pthread_sigmask(SIG_UNBLOCK, &set, &oldset);
+
+ if (sigsetjmp(sigjump, 1)) {
+ fprintf(stderr, "file_ram_alloc: failed to preallocate pages\n");
+ exit(1);
+ }
+
+ /* MAP_POPULATE silently ignores failures */
+ for (i = 0; i < (memory/hpagesize)-1; i++) {
+ memset(area + (hpagesize*i), 0, 1);
+ }
+
+ ret = sigaction(SIGBUS, &oldact, NULL);
+ if (ret) {
+ perror("file_ram_alloc: failed to reinstall signal handler");
+ exit(1);
+ }
+
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ }
+
block->fd = fd;
return area;
}
diff --git a/qemu-options.hx b/qemu-options.hx
index 5dc8b75..3674b3c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -228,7 +228,6 @@ STEXI
Allocate guest RAM from a temporarily created file in @var{path}.
ETEXI
-#ifdef MAP_POPULATE
DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
"-mem-prealloc preallocate guest memory (use with -mem-path)\n",
QEMU_ARCH_ALL)
@@ -237,7 +236,6 @@ STEXI
@findex -mem-prealloc
Preallocate memory when using -mem-path.
ETEXI
-#endif
DEF("k", HAS_ARG, QEMU_OPTION_k,
"-k language use keyboard layout (for example 'fr' for French)\n",
diff --git a/vl.c b/vl.c
index b42ac67..1e28c5c 100644
--- a/vl.c
+++ b/vl.c
@@ -188,9 +188,7 @@ static int display_remote;
const char* keyboard_layout = NULL;
ram_addr_t ram_size;
const char *mem_path = NULL;
-#ifdef MAP_POPULATE
int mem_prealloc = 0; /* force preallocation of physical target memory */
-#endif
int nb_nics;
NICInfo nd_table[MAX_NICS];
int autostart;
@@ -3205,11 +3203,9 @@ 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 = 1;
break;
-#endif
case QEMU_OPTION_d:
log_mask = optarg;
break;
- [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, (continued)
- [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Marcelo Tosatti, 2013/10/07
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Paolo Bonzini, 2013/10/08
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Marcelo Tosatti, 2013/10/08
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Paolo Bonzini, 2013/10/09
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Marcelo Tosatti, 2013/10/09
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Paolo Bonzini, 2013/10/09
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Paolo Bonzini, 2013/10/10
- Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Marcelo Tosatti, 2013/10/10
Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Paolo Bonzini, 2013/10/28
Re: [Qemu-devel] [patch 1/2] qemu: mempath: prefault pages manually, Peter Maydell, 2013/10/28
Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Markus Armbruster, 2013/10/08
- Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Paolo Bonzini, 2013/10/08
- Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Marcelo Tosatti, 2013/10/08
- Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Markus Armbruster, 2013/10/09
- Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Marcelo Tosatti, 2013/10/09
- Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Paolo Bonzini, 2013/10/09
- Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Marcelo Tosatti, 2013/10/10
Re: [Qemu-devel] [patch 0/2] force -mem-path RAM allocation, Paolo Bonzini, 2013/10/09