From patchwork Mon Jun 9 10:25:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 357405 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 A1199140092 for ; Mon, 9 Jun 2014 20:40:12 +1000 (EST) Received: from localhost ([::1]:60047 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wtwzp-0001Ap-QS for incoming@patchwork.ozlabs.org; Mon, 09 Jun 2014 06:40:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41333) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wtwol-00040a-LD for qemu-devel@nongnu.org; Mon, 09 Jun 2014 06:28:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wtwog-0001AP-UI for qemu-devel@nongnu.org; Mon, 09 Jun 2014 06:28:43 -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 1Wtwog-0000xR-1u for qemu-devel@nongnu.org; Mon, 09 Jun 2014 06:28:38 -0400 X-IronPort-AV: E=Sophos;i="4.98,1001,1392134400"; d="scan'208";a="31650605" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 09 Jun 2014 18:25:59 +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 s59ASaiJ021709; Mon, 9 Jun 2014 18:28:36 +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:38 +0800 From: Hu Tao To: Date: Mon, 9 Jun 2014 18:25:25 +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 20/29] hostmem: allow preallocation of any memory region 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 And allow preallocation of file-based memory even without -mem-prealloc. Some care is necessary because -mem-prealloc does not allow disabling preallocation for hostmem-file. Signed-off-by: Paolo Bonzini Signed-off-by: Hu Tao --- backends/hostmem-file.c | 3 +++ backends/hostmem.c | 42 ++++++++++++++++++++++++++++++++++++++++++ exec.c | 7 +++++++ include/exec/memory.h | 10 ++++++++++ include/exec/ram_addr.h | 1 + include/sysemu/hostmem.h | 1 + memory.c | 11 +++++++++++ 7 files changed, 75 insertions(+) diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index b8df933..d3a7ef3 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -9,7 +9,9 @@ * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ +#include "qemu-common.h" #include "sysemu/hostmem.h" +#include "sysemu/sysemu.h" #include "qom/object_interfaces.h" /* hostmem-file.c */ @@ -46,6 +48,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) error_setg(errp, "-mem-path not supported on this host"); #else if (!memory_region_size(&backend->mr)) { + backend->force_prealloc = mem_prealloc; memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), object_get_canonical_path(OBJECT(backend)), backend->size, diff --git a/backends/hostmem.c b/backends/hostmem.c index fa306b4..e437275 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -105,6 +105,41 @@ static void host_memory_backend_set_dump(Object *obj, bool value, Error **errp) } } +static bool host_memory_backend_get_prealloc(Object *obj, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(obj); + + return backend->prealloc || backend->force_prealloc; +} + +static void host_memory_backend_set_prealloc(Object *obj, bool value, + Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(obj); + + if (backend->force_prealloc) { + if (value) { + error_setg(errp, + "remove -mem-prealloc to use the prealloc property"); + return; + } + } + + if (!memory_region_size(&backend->mr)) { + backend->prealloc = value; + return; + } + + if (value && !backend->prealloc) { + int fd = memory_region_get_fd(&backend->mr); + void *ptr = memory_region_get_ram_ptr(&backend->mr); + uint64_t sz = memory_region_size(&backend->mr); + + os_mem_prealloc(fd, ptr, sz); + backend->prealloc = true; + } +} + static void host_memory_backend_init(Object *obj) { HostMemoryBackend *backend = MEMORY_BACKEND(obj); @@ -113,6 +148,7 @@ static void host_memory_backend_init(Object *obj) "mem-merge", true); backend->dump = qemu_opt_get_bool(qemu_get_machine_opts(), "dump-guest-core", true); + backend->prealloc = mem_prealloc; object_property_add_bool(obj, "merge", host_memory_backend_get_merge, @@ -120,6 +156,9 @@ static void host_memory_backend_init(Object *obj) object_property_add_bool(obj, "dump", host_memory_backend_get_dump, host_memory_backend_set_dump, NULL); + object_property_add_bool(obj, "prealloc", + host_memory_backend_get_prealloc, + host_memory_backend_set_prealloc, NULL); object_property_add(obj, "size", "int", host_memory_backend_get_size, host_memory_backend_set_size, NULL, NULL, NULL); @@ -165,6 +204,9 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) if (!backend->dump) { qemu_madvise(ptr, sz, QEMU_MADV_DONTDUMP); } + if (backend->prealloc) { + os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz); + } } } diff --git a/exec.c b/exec.c index 739f0cf..520d673 100644 --- a/exec.c +++ b/exec.c @@ -1432,6 +1432,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) } #endif /* !_WIN32 */ +int qemu_get_ram_fd(ram_addr_t addr) +{ + RAMBlock *block = qemu_get_ram_block(addr); + + return block->fd; +} + /* Return a host pointer to ram allocated with qemu_ram_alloc. With the exception of the softmmu code in this file, this should only be used for local memory (e.g. video ram) that the device owns, diff --git a/include/exec/memory.h b/include/exec/memory.h index 82d7781..36226f7 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -534,6 +534,16 @@ bool memory_region_is_logging(MemoryRegion *mr); bool memory_region_is_rom(MemoryRegion *mr); /** + * memory_region_get_fd: Get a file descriptor backing a RAM memory region. + * + * Returns a file descriptor backing a file-based RAM memory region, + * or -1 if the region is not a file-based RAM memory region. + * + * @mr: the RAM or alias memory region being queried. + */ +int memory_region_get_fd(MemoryRegion *mr); + +/** * memory_region_get_ram_ptr: Get a pointer into a RAM memory region. * * Returns a host pointer to a RAM memory region (created with diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index f9518a6..d352f60 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -27,6 +27,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, 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); +int qemu_get_ram_fd(ram_addr_t addr); void *qemu_get_ram_ptr(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr); diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index ede5ec9..4cae673 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -53,6 +53,7 @@ struct HostMemoryBackend { /* protected */ uint64_t size; bool merge, dump; + bool prealloc, force_prealloc; MemoryRegion mr; }; diff --git a/memory.c b/memory.c index 310729a..bcef72b 100644 --- a/memory.c +++ b/memory.c @@ -1258,6 +1258,17 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr, cpu_physical_memory_reset_dirty(mr->ram_addr + addr, size, client); } +int memory_region_get_fd(MemoryRegion *mr) +{ + if (mr->alias) { + return memory_region_get_fd(mr->alias); + } + + assert(mr->terminates); + + return qemu_get_ram_fd(mr->ram_addr & TARGET_PAGE_MASK); +} + void *memory_region_get_ram_ptr(MemoryRegion *mr) { if (mr->alias) {