From patchwork Wed Mar 26 10:37:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 333824 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AF80F14008C for ; Wed, 26 Mar 2014 22:29:01 +1100 (EST) Received: from localhost ([::1]:47076 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WSm0x-0002P9-Nv for incoming@patchwork.ozlabs.org; Wed, 26 Mar 2014 07:28:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37819) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WSliY-0001Vw-H0 for qemu-devel@nongnu.org; Wed, 26 Mar 2014 07:10:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WSliS-0002mB-GX for qemu-devel@nongnu.org; Wed, 26 Mar 2014 07:09:58 -0400 Received: from [59.151.112.132] (port=3738 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WSliR-0002lt-AD for qemu-devel@nongnu.org; Wed, 26 Mar 2014 07:09:52 -0400 X-IronPort-AV: E=Sophos;i="4.97,734,1389715200"; d="scan'208";a="28487325" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 26 Mar 2014 18:34:32 +0800 Received: from G08CNEXCHPEKD01.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s2QAapvx003096; Wed, 26 Mar 2014 18:36:54 +0800 Received: from G08CNEXMBPEKD03.g08.fujitsu.local ([10.167.33.86]) by G08CNEXCHPEKD01.g08.fujitsu.local ([10.167.33.80]) with mapi id 14.03.0146.002; Wed, 26 Mar 2014 18:37:05 +0800 From: "hutao@cn.fujitsu.com" To: "qemu-devel@nongnu.org" Thread-Topic: [PATCH v3 19/34] memory: move preallocation code out of exec.c Thread-Index: AQHPSN9URA3GHs/TrE2G4ZswWfdYow== Date: Wed, 26 Mar 2014 10:37:00 +0000 Message-ID: References: In-Reply-To: Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.167.226.102] MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 59.151.112.132 Cc: "ehabkost@redhat.com" , "imammedo@redhat.com" , "mtosatti@redhat.com" , Paolo Bonzini , "a.motakis@virtualopensystems.com" , "gaowanlong@cn.fujitsu.com" Subject: [Qemu-devel] [PATCH v3 19/34] memory: move preallocation code out of exec.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Paolo Bonzini So that backends can use it. Signed-off-by: Paolo Bonzini --- exec.c | 44 +------------------------------ include/qemu/osdep.h | 2 ++ util/oslib-posix.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 43 deletions(-) diff --git a/exec.c b/exec.c index 1e51b2f..710e025 100644 --- a/exec.c +++ b/exec.c @@ -1012,13 +1012,6 @@ 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, @@ -1088,42 +1081,7 @@ static void *file_ram_alloc(RAMBlock *block, } 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); 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); + os_mem_prealloc(fd, area, memory); } block->fd = fd; diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index ffb2966..9c1a119 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -251,4 +251,6 @@ void qemu_init_auxval(char **envp); void qemu_set_tty_echo(int fd, bool echo); +void os_mem_prealloc(int fd, char *area, size_t sz); + #endif diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 8e9c770..a22c97d 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -46,6 +46,7 @@ extern int daemon(int, int); #else # define QEMU_VMALLOC_ALIGN getpagesize() #endif +#define HUGETLBFS_MAGIC 0x958458f6 #include #include @@ -58,9 +59,12 @@ extern int daemon(int, int); #include "qemu/sockets.h" #include #include +#include +#include #ifdef CONFIG_LINUX #include +#include #endif #ifdef __FreeBSD__ @@ -332,3 +336,72 @@ char *qemu_get_exec_dir(void) { 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("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 */ + 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("file_ram_alloc: failed to reinstall signal handler"); + exit(1); + } + + pthread_sigmask(SIG_SETMASK, &oldset, NULL); +}