mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-12-17 21:26:13 -07: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
3 changed files with 47 additions and 18 deletions
59
exec.c
59
exec.c
|
|
@ -904,6 +904,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)
|
||||
|
|
@ -913,9 +920,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);
|
||||
|
|
@ -963,21 +967,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue