mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
qemu: mempath: prefault pages manually (v4)
v4: s/fail/failed/ (Peter Maydell) Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
fb541ca59c
commit
ef36fa1492
59
exec.c
59
exec.c
|
@ -904,6 +904,13 @@ static long gethugepagesize(const char *path)
|
||||||
return fs.f_bsize;
|
return fs.f_bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sigjmp_buf sigjump;
|
||||||
|
|
||||||
|
static void sigbus_handler(int signal)
|
||||||
|
{
|
||||||
|
siglongjmp(sigjump, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void *file_ram_alloc(RAMBlock *block,
|
static void *file_ram_alloc(RAMBlock *block,
|
||||||
ram_addr_t memory,
|
ram_addr_t memory,
|
||||||
const char *path)
|
const char *path)
|
||||||
|
@ -913,9 +920,6 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||||
char *c;
|
char *c;
|
||||||
void *area;
|
void *area;
|
||||||
int fd;
|
int fd;
|
||||||
#ifdef MAP_POPULATE
|
|
||||||
int flags;
|
|
||||||
#endif
|
|
||||||
unsigned long hpagesize;
|
unsigned long hpagesize;
|
||||||
|
|
||||||
hpagesize = gethugepagesize(path);
|
hpagesize = gethugepagesize(path);
|
||||||
|
@ -963,21 +967,52 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||||
if (ftruncate(fd, memory))
|
if (ftruncate(fd, memory))
|
||||||
perror("ftruncate");
|
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);
|
area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||||
#endif
|
|
||||||
if (area == MAP_FAILED) {
|
if (area == MAP_FAILED) {
|
||||||
perror("file_ram_alloc: can't mmap RAM pages");
|
perror("file_ram_alloc: can't mmap RAM pages");
|
||||||
close(fd);
|
close(fd);
|
||||||
return (NULL);
|
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;
|
block->fd = fd;
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,6 @@ STEXI
|
||||||
Allocate guest RAM from a temporarily created file in @var{path}.
|
Allocate guest RAM from a temporarily created file in @var{path}.
|
||||||
ETEXI
|
ETEXI
|
||||||
|
|
||||||
#ifdef MAP_POPULATE
|
|
||||||
DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
|
DEF("mem-prealloc", 0, QEMU_OPTION_mem_prealloc,
|
||||||
"-mem-prealloc preallocate guest memory (use with -mem-path)\n",
|
"-mem-prealloc preallocate guest memory (use with -mem-path)\n",
|
||||||
QEMU_ARCH_ALL)
|
QEMU_ARCH_ALL)
|
||||||
|
@ -237,7 +236,6 @@ STEXI
|
||||||
@findex -mem-prealloc
|
@findex -mem-prealloc
|
||||||
Preallocate memory when using -mem-path.
|
Preallocate memory when using -mem-path.
|
||||||
ETEXI
|
ETEXI
|
||||||
#endif
|
|
||||||
|
|
||||||
DEF("k", HAS_ARG, QEMU_OPTION_k,
|
DEF("k", HAS_ARG, QEMU_OPTION_k,
|
||||||
"-k language use keyboard layout (for example 'fr' for French)\n",
|
"-k language use keyboard layout (for example 'fr' for French)\n",
|
||||||
|
|
4
vl.c
4
vl.c
|
@ -188,9 +188,7 @@ static int display_remote;
|
||||||
const char* keyboard_layout = NULL;
|
const char* keyboard_layout = NULL;
|
||||||
ram_addr_t ram_size;
|
ram_addr_t ram_size;
|
||||||
const char *mem_path = NULL;
|
const char *mem_path = NULL;
|
||||||
#ifdef MAP_POPULATE
|
|
||||||
int mem_prealloc = 0; /* force preallocation of physical target memory */
|
int mem_prealloc = 0; /* force preallocation of physical target memory */
|
||||||
#endif
|
|
||||||
int nb_nics;
|
int nb_nics;
|
||||||
NICInfo nd_table[MAX_NICS];
|
NICInfo nd_table[MAX_NICS];
|
||||||
int autostart;
|
int autostart;
|
||||||
|
@ -3206,11 +3204,9 @@ int main(int argc, char **argv, char **envp)
|
||||||
case QEMU_OPTION_mempath:
|
case QEMU_OPTION_mempath:
|
||||||
mem_path = optarg;
|
mem_path = optarg;
|
||||||
break;
|
break;
|
||||||
#ifdef MAP_POPULATE
|
|
||||||
case QEMU_OPTION_mem_prealloc:
|
case QEMU_OPTION_mem_prealloc:
|
||||||
mem_prealloc = 1;
|
mem_prealloc = 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case QEMU_OPTION_d:
|
case QEMU_OPTION_d:
|
||||||
log_mask = optarg;
|
log_mask = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue