From patchwork Tue May 6 09:27:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hu Tao X-Patchwork-Id: 346122 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id EF98914131B for ; Tue, 6 May 2014 19:53:31 +1000 (EST) Received: from localhost ([::1]:33991 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Whc41-00081o-O4 for incoming@patchwork.ozlabs.org; Tue, 06 May 2014 05:53:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39220) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WhboN-0008Sd-0h for qemu-devel@nongnu.org; Tue, 06 May 2014 05:37:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WhboD-0008II-2A for qemu-devel@nongnu.org; Tue, 06 May 2014 05:37:18 -0400 Received: from [59.151.112.132] (port=39804 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WhboC-0008ER-7S for qemu-devel@nongnu.org; Tue, 06 May 2014 05:37:08 -0400 X-IronPort-AV: E=Sophos;i="4.97,996,1389715200"; d="scan'208";a="30131324" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 06 May 2014 17:27:35 +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 s469U5tG003109; Tue, 6 May 2014 17:30:05 +0800 Received: from G08FNSTD100614.fnst.cn.fujitsu.com (10.167.226.102) by G08CNEXCHPEKD01.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.146.2; Tue, 6 May 2014 17:30:14 +0800 From: Hu Tao To: Date: Tue, 6 May 2014 17:27:44 +0800 Message-ID: <8e0ba625c09eb35fc4ceb1cc08bccd5a094f54c7.1399365798.git.hutao@cn.fujitsu.com> X-Mailer: git-send-email 1.8.5.2.229.g4448466 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: Paolo Bonzini , Igor Mammedov Subject: [Qemu-devel] [PATCH v3.1 23/31] hostmem: add property to map memory with MAP_SHARED 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 A new "share" property can be used with the "memory-file" backend to map memory with MAP_SHARED instead of MAP_PRIVATE. Signed-off-by: Paolo Bonzini Signed-off-by: Hu Tao --- backends/hostmem-file.c | 26 +++++++++++++++++++++++++- exec.c | 18 ++++++++++-------- include/exec/memory.h | 2 ++ include/exec/ram_addr.h | 3 ++- memory.c | 3 ++- numa.c | 2 +- 6 files changed, 42 insertions(+), 12 deletions(-) diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index 67328b9..7f30011 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -28,6 +28,8 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile; struct HostMemoryBackendFile { HostMemoryBackend parent_obj; + + bool share; char *mem_path; }; @@ -51,7 +53,7 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) backend->force_prealloc = mem_prealloc; memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), object_get_canonical_path(OBJECT(backend)), - backend->size, + backend->size, fb->share, fb->mem_path, errp); } #endif @@ -87,9 +89,31 @@ static void set_mem_path(Object *o, const char *str, Error **errp) fb->mem_path = g_strdup(str); } +static bool file_memory_backend_get_share(Object *o, Error **errp) +{ + HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o); + + return fb->share; +} + +static void file_memory_backend_set_share(Object *o, bool value, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o); + + if (memory_region_size(&backend->mr)) { + error_setg(errp, "cannot change property value"); + return; + } + fb->share = value; +} + static void file_backend_instance_init(Object *o) { + object_property_add_bool(o, "share", + file_memory_backend_get_share, + file_memory_backend_set_share, NULL); object_property_add_str(o, "mem-path", get_mem_path, set_mem_path, NULL); } diff --git a/exec.c b/exec.c index fab45b5..85fb85c 100644 --- a/exec.c +++ b/exec.c @@ -73,6 +73,9 @@ static MemoryRegion io_mem_unassigned; /* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */ #define RAM_PREALLOC (1 << 0) +/* RAM is mmap-ed with MAP_SHARED */ +#define RAM_SHARED (1 << 1) + #endif struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus); @@ -1075,7 +1078,9 @@ static void *file_ram_alloc(RAMBlock *block, perror("ftruncate"); } - area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + area = mmap(0, memory, PROT_READ | PROT_WRITE, + (block->flags & RAM_SHARED ? MAP_SHARED : MAP_PRIVATE), + fd, 0); if (area == MAP_FAILED) { error_setg_errno(errp, errno, "unable to map backing store for hugepages"); @@ -1271,7 +1276,7 @@ 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, + bool share, const char *mem_path, Error **errp) { RAMBlock *new_block; @@ -1296,6 +1301,7 @@ ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, new_block = g_malloc0(sizeof(*new_block)); new_block->mr = mr; new_block->length = size; + new_block->flags = share ? RAM_SHARED : 0; new_block->host = file_ram_alloc(new_block, size, mem_path, errp); if (!new_block->host) { @@ -1398,12 +1404,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length) flags = MAP_FIXED; munmap(vaddr, length); if (block->fd >= 0) { -#ifdef MAP_POPULATE - flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED : - MAP_PRIVATE; -#else - flags |= MAP_PRIVATE; -#endif + flags |= (block->flags & RAM_SHARED ? + MAP_SHARED : MAP_PRIVATE); area = mmap(vaddr, length, PROT_READ | PROT_WRITE, flags, block->fd, offset); } else { diff --git a/include/exec/memory.h b/include/exec/memory.h index 846834e..21443bc 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -321,6 +321,7 @@ void memory_region_init_ram(MemoryRegion *mr, * @owner: the object that tracks the region's reference count * @name: the name of the region. * @size: size of the region. + * @share: %true if memory must be mmaped with the MAP_SHARED flag * @path: the path in which to allocate the RAM. * @errp: pointer to Error*, to store an error if it happens. */ @@ -328,6 +329,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, struct Object *owner, const char *name, uint64_t size, + bool share, const char *path, Error **errp); #endif diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index d352f60..1d4ac74 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -23,7 +23,8 @@ #include "hw/xen/xen.h" ram_addr_t qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr, - const char *mem_path, Error **errp); + bool share, 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 118704d..202869a 100644 --- a/memory.c +++ b/memory.c @@ -1025,6 +1025,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, struct Object *owner, const char *name, uint64_t size, + bool share, const char *path, Error **errp) { @@ -1032,7 +1033,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, mr->ram = true; mr->terminates = true; mr->destructor = memory_region_destructor_ram; - mr->ram_addr = qemu_ram_alloc_from_file(size, mr, path, errp); + mr->ram_addr = qemu_ram_alloc_from_file(size, mr, share, path, errp); } #endif diff --git a/numa.c b/numa.c index 966cacc..fa117f0 100644 --- a/numa.c +++ b/numa.c @@ -232,7 +232,7 @@ static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner, if (mem_path) { #ifdef __linux__ Error *err = NULL; - memory_region_init_ram_from_file(mr, owner, name, ram_size, + memory_region_init_ram_from_file(mr, owner, name, ram_size, false, mem_path, &err); /* Legacy behavior: if allocation failed, fall back to