From patchwork Mon Jun 9 10:25:20 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 357394 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 8BBD4140076 for ; Mon, 9 Jun 2014 20:34:44 +1000 (EST) Received: from localhost ([::1]:59984 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WtwuW-0002tI-KC for incoming@patchwork.ozlabs.org; Mon, 09 Jun 2014 06:34:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41193) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WtwoQ-0003NY-ON for qemu-devel@nongnu.org; Mon, 09 Jun 2014 06:28:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WtwoL-00014w-VE for qemu-devel@nongnu.org; Mon, 09 Jun 2014 06:28:22 -0400 Received: from [59.151.112.132] (port=38459 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WtwoL-0000xR-52 for qemu-devel@nongnu.org; Mon, 09 Jun 2014 06:28:17 -0400 X-IronPort-AV: E=Sophos;i="4.98,1001,1392134400"; d="scan'208";a="31650577" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 09 Jun 2014 18:25:38 +0800 Received: from G08CNEXCHPEKD03.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id s59ASGV6021665; Mon, 9 Jun 2014 18:28:16 +0800 Received: from G08FNSTD100614.fnst.cn.fujitsu.com (10.167.226.102) by G08CNEXCHPEKD03.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Mon, 9 Jun 2014 18:28:17 +0800 From: Hu Tao To: Date: Mon, 9 Jun 2014 18:25:20 +0800 Message-ID: X-Mailer: git-send-email 1.9.3 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.167.226.102] X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 59.151.112.132 Cc: Yasunori Goto , Paolo Bonzini , "Michael S. Tsirkin" , Eduardo Habkost , Igor Mammedov Subject: [Qemu-devel] [PATCH v4 15/29] memory: add error propagation to file-based RAM allocation 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 Right now, -mem-path will fall back to RAM-based allocation in some cases. This should never happen with "-object memory-file", prepare the code by adding correct error propagation. Signed-off-by: Paolo Bonzini Signed-off-by: Hu Tao --- exec.c | 36 ++++++++++++++++++++++++------------ include/exec/memory.h | 5 ++++- include/exec/ram_addr.h | 2 +- memory.c | 5 +++-- numa.c | 13 ++++++++++++- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/exec.c b/exec.c index cbbb2a7..36301e2 100644 --- a/exec.c +++ b/exec.c @@ -1020,7 +1020,8 @@ static void sigbus_handler(int signal) static void *file_ram_alloc(RAMBlock *block, ram_addr_t memory, - const char *path) + const char *path, + Error **errp) { char *filename; char *sanitized_name; @@ -1039,7 +1040,8 @@ static void *file_ram_alloc(RAMBlock *block, } if (kvm_enabled() && !kvm_has_sync_mmu()) { - fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n"); + error_setg(errp, + "host lacks kvm mmu notifiers, -mem-path unsupported\n"); goto error; } @@ -1056,7 +1058,8 @@ static void *file_ram_alloc(RAMBlock *block, fd = mkstemp(filename); if (fd < 0) { - perror("unable to create backing store for hugepages"); + error_setg_errno(errp, errno, + "unable to create backing store for hugepages"); g_free(filename); goto error; } @@ -1071,12 +1074,14 @@ static void *file_ram_alloc(RAMBlock *block, * If anything goes wrong with it under other filesystems, * mmap will fail. */ - if (ftruncate(fd, memory)) + if (ftruncate(fd, memory)) { perror("ftruncate"); + } area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (area == MAP_FAILED) { - perror("file_ram_alloc: can't mmap RAM pages"); + error_setg_errno(errp, errno, + "unable to map backing store for hugepages"); close(fd); goto error; } @@ -1304,13 +1309,14 @@ static ram_addr_t ram_block_add(RAMBlock *new_block) #ifdef __linux__ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, - const char *mem_path) + const char *mem_path, + Error **errp) { RAMBlock *new_block; if (xen_enabled()) { - fprintf(stderr, "-mem-path not supported with Xen\n"); - exit(1); + error_setg(errp, "-mem-path not supported with Xen\n"); + return -1; } if (phys_mem_alloc != qemu_anon_ram_alloc) { @@ -1319,16 +1325,22 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, * phys_mem_alloc, but we haven't bothered to provide * a hook there. */ - fprintf(stderr, - "-mem-path not supported with this accelerator\n"); - exit(1); + error_setg(errp, + "-mem-path not supported with this accelerator\n"); + return -1; } size = TARGET_PAGE_ALIGN(size); new_block = g_malloc0(sizeof(*new_block)); new_block->mr = mr; new_block->length = size; - new_block->host = file_ram_alloc(new_block, size, mem_path); + new_block->host = file_ram_alloc(new_block, size, + mem_path, errp); + if (!new_block->host) { + g_free(new_block); + return -1; + } + return ram_block_add(new_block); } #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index 58c3fe4..82d7781 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -31,6 +31,7 @@ #include "qemu/queue.h" #include "qemu/int128.h" #include "qemu/notify.h" +#include "qapi/error.h" #define MAX_PHYS_ADDR_SPACE_BITS 62 #define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1) @@ -321,12 +322,14 @@ void memory_region_init_ram(MemoryRegion *mr, * @name: the name of the region. * @size: size of the region. * @path: the path in which to allocate the RAM. + * @errp: pointer to Error*, to store an error if it happens. */ void memory_region_init_ram_from_file(MemoryRegion *mr, struct Object *owner, const char *name, uint64_t size, - const char *path); + const char *path, + Error **errp); #endif /** diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index dedb258..f9518a6 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -23,7 +23,7 @@ #include "hw/xen/xen.h" ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, - const char *mem_path); + const char *mem_path, Error **errp); ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, MemoryRegion *mr); ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr); diff --git a/memory.c b/memory.c index 6192377..310729a 100644 --- a/memory.c +++ b/memory.c @@ -1025,13 +1025,14 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, struct Object *owner, const char *name, uint64_t size, - const char *path) + const char *path, + Error **errp) { memory_region_init(mr, owner, name, size); mr->ram = true; mr->terminates = true; mr->destructor = memory_region_destructor_ram; - mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path); + mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp); } #endif diff --git a/numa.c b/numa.c index 7846ba8..039d401 100644 --- a/numa.c +++ b/numa.c @@ -230,7 +230,18 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner, { if (mem_path) { #ifdef __linux__ - memory_region_init_ram_from_file(mr, owner, name, ram_size, mem_path); + Error *err = NULL; + memory_region_init_ram_from_file(mr, owner, name, ram_size, + mem_path, &err); + + /* Legacy behavior: if allocation failed, fall back to + * regular RAM allocation. + */ + if (!memory_region_size(mr)) { + qerror_report_err(err); + error_free(err); + memory_region_init_ram(mr, owner, name, ram_size); + } #else fprintf(stderr, "-mem-path not supported on this host\n"); exit(1);