memory: move preallocation code out of exec.c
So that backends can use it. Since we need the page size for efficiency, move code to compute it out of translate-all.c and into util/oslib-win32.c. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
e1c57ab86f
commit
38183310be
44
exec.c
44
exec.c
@ -1011,13 +1011,6 @@ 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)
|
||||||
@ -1082,42 +1075,7 @@ static void *file_ram_alloc(RAMBlock *block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mem_prealloc) {
|
if (mem_prealloc) {
|
||||||
int ret, i;
|
os_mem_prealloc(fd, area, memory);
|
||||||
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); 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;
|
||||||
|
@ -251,4 +251,6 @@ void qemu_init_auxval(char **envp);
|
|||||||
|
|
||||||
void qemu_set_tty_echo(int fd, bool echo);
|
void qemu_set_tty_echo(int fd, bool echo);
|
||||||
|
|
||||||
|
void os_mem_prealloc(int fd, char *area, size_t sz);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -89,6 +89,8 @@ static inline void os_setup_post(void) {}
|
|||||||
void os_set_line_buffering(void);
|
void os_set_line_buffering(void);
|
||||||
static inline void os_set_proc_name(const char *dummy) {}
|
static inline void os_set_proc_name(const char *dummy) {}
|
||||||
|
|
||||||
|
size_t getpagesize(void);
|
||||||
|
|
||||||
#if !defined(EPROTONOSUPPORT)
|
#if !defined(EPROTONOSUPPORT)
|
||||||
# define EPROTONOSUPPORT EINVAL
|
# define EPROTONOSUPPORT EINVAL
|
||||||
#endif
|
#endif
|
||||||
|
@ -295,14 +295,7 @@ void page_size_init(void)
|
|||||||
{
|
{
|
||||||
/* NOTE: we can always suppose that qemu_host_page_size >=
|
/* NOTE: we can always suppose that qemu_host_page_size >=
|
||||||
TARGET_PAGE_SIZE */
|
TARGET_PAGE_SIZE */
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEM_INFO system_info;
|
|
||||||
|
|
||||||
GetSystemInfo(&system_info);
|
|
||||||
qemu_real_host_page_size = system_info.dwPageSize;
|
|
||||||
#else
|
|
||||||
qemu_real_host_page_size = getpagesize();
|
qemu_real_host_page_size = getpagesize();
|
||||||
#endif
|
|
||||||
if (qemu_host_page_size == 0) {
|
if (qemu_host_page_size == 0) {
|
||||||
qemu_host_page_size = qemu_real_host_page_size;
|
qemu_host_page_size = qemu_real_host_page_size;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ extern int daemon(int, int);
|
|||||||
#else
|
#else
|
||||||
# define QEMU_VMALLOC_ALIGN getpagesize()
|
# define QEMU_VMALLOC_ALIGN getpagesize()
|
||||||
#endif
|
#endif
|
||||||
|
#define HUGETLBFS_MAGIC 0x958458f6
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -58,9 +59,12 @@ extern int daemon(int, int);
|
|||||||
#include "qemu/sockets.h"
|
#include "qemu/sockets.h"
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <sys/signal.h>
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX
|
#ifdef CONFIG_LINUX
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
@ -332,3 +336,72 @@ char *qemu_get_exec_dir(void)
|
|||||||
{
|
{
|
||||||
return g_strdup(exec_dir);
|
return g_strdup(exec_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static sigjmp_buf sigjump;
|
||||||
|
|
||||||
|
static void sigbus_handler(int signal)
|
||||||
|
{
|
||||||
|
siglongjmp(sigjump, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t fd_getpagesize(int fd)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_LINUX
|
||||||
|
struct statfs fs;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (fd != -1) {
|
||||||
|
do {
|
||||||
|
ret = fstatfs(fd, &fs);
|
||||||
|
} while (ret != 0 && errno == EINTR);
|
||||||
|
|
||||||
|
if (ret == 0 && fs.f_type == HUGETLBFS_MAGIC) {
|
||||||
|
return fs.f_bsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return getpagesize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void os_mem_prealloc(int fd, char *area, size_t memory)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
struct sigaction act, oldact;
|
||||||
|
sigset_t set, oldset;
|
||||||
|
size_t hpagesize = fd_getpagesize(fd);
|
||||||
|
|
||||||
|
memset(&act, 0, sizeof(act));
|
||||||
|
act.sa_handler = &sigbus_handler;
|
||||||
|
act.sa_flags = 0;
|
||||||
|
|
||||||
|
ret = sigaction(SIGBUS, &act, &oldact);
|
||||||
|
if (ret) {
|
||||||
|
perror("os_mem_prealloc: 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, "os_mem_prealloc: failed to preallocate pages\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MAP_POPULATE silently ignores failures */
|
||||||
|
memory = (memory + hpagesize - 1) & -hpagesize;
|
||||||
|
for (i = 0; i < (memory/hpagesize); i++) {
|
||||||
|
memset(area + (hpagesize*i), 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sigaction(SIGBUS, &oldact, NULL);
|
||||||
|
if (ret) {
|
||||||
|
perror("os_mem_prealloc: failed to reinstall signal handler");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||||
|
}
|
||||||
|
@ -350,3 +350,22 @@ gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout)
|
|||||||
|
|
||||||
return num_completed;
|
return num_completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getpagesize(void)
|
||||||
|
{
|
||||||
|
SYSTEM_INFO system_info;
|
||||||
|
|
||||||
|
GetSystemInfo(&system_info);
|
||||||
|
return system_info.dwPageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void os_mem_prealloc(int fd, char *area, size_t memory)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t pagesize = getpagesize();
|
||||||
|
|
||||||
|
memory = (memory + pagesize - 1) & -pagesize;
|
||||||
|
for (i = 0; i < memory / pagesize; i++) {
|
||||||
|
memset(area + pagesize * i, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user