From patchwork Wed Feb 28 07:25:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 10246931 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DAAB960384 for ; Wed, 28 Feb 2018 07:27:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C46A0274D0 for ; Wed, 28 Feb 2018 07:27:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B89B827F93; Wed, 28 Feb 2018 07:27:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 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 mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CD3D327D29 for ; Wed, 28 Feb 2018 07:27:49 +0000 (UTC) Received: from localhost ([::1]:42614 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eqw9V-0005mu-1p for patchwork-qemu-devel@patchwork.kernel.org; Wed, 28 Feb 2018 02:27:49 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55208) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eqw87-0004aj-1V for qemu-devel@nongnu.org; Wed, 28 Feb 2018 02:26:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eqw85-0000F1-5j for qemu-devel@nongnu.org; Wed, 28 Feb 2018 02:26:23 -0500 Received: from mga02.intel.com ([134.134.136.20]:30637) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eqw84-0000CT-NW for qemu-devel@nongnu.org; Wed, 28 Feb 2018 02:26:21 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Feb 2018 23:26:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,404,1515484800"; d="scan'208";a="34718483" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.13.35]) by orsmga001.jf.intel.com with ESMTP; 27 Feb 2018 23:26:18 -0800 From: Haozhong Zhang To: qemu-devel@nongnu.org Date: Wed, 28 Feb 2018 15:25:52 +0800 Message-Id: <20180228072558.7434-3-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180228072558.7434-1-haozhong.zhang@intel.com> References: <20180228072558.7434-1-haozhong.zhang@intel.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 134.134.136.20 Subject: [Qemu-devel] [PATCH v4 2/8] hostmem-file: add the 'pmem' option X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Haozhong Zhang , Xiao Guangrong , mst@redhat.com, Juan Quintela , dgilbert@redhat.com, Stefan Hajnoczi , Paolo Bonzini , Igor Mammedov , Dan Williams , Eduardo Habkost Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When QEMU emulates vNVDIMM labels and migrates vNVDIMM devices, it needs to know whether the backend storage is a real persistent memory, in order to decide whether special operations should be performed to ensure the data persistence. This boolean option 'pmem' allows users to specify whether the backend storage of memory-backend-file is a real persistent memory. If 'pmem=on', QEMU will set the flag RAM_PMEM in the RAM block of the corresponding memory region. Signed-off-by: Haozhong Zhang --- backends/hostmem-file.c | 26 +++++++++++++++++++++++++- docs/nvdimm.txt | 14 ++++++++++++++ exec.c | 13 ++++++++++++- include/exec/memory.h | 2 ++ include/exec/ram_addr.h | 3 +++ qemu-options.hx | 9 ++++++++- 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index 30df843d90..5d706d471f 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -34,6 +34,7 @@ struct HostMemoryBackendFile { bool discard_data; char *mem_path; uint64_t align; + bool is_pmem; }; static void @@ -59,7 +60,8 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp) memory_region_init_ram_from_file(&backend->mr, OBJECT(backend), path, backend->size, fb->align, - backend->share ? QEMU_RAM_SHARE : 0, + (backend->share ? QEMU_RAM_SHARE : 0) | + (fb->is_pmem ? QEMU_RAM_PMEM : 0), fb->mem_path, errp); g_free(path); } @@ -131,6 +133,25 @@ static void file_memory_backend_set_align(Object *o, Visitor *v, error_propagate(errp, local_err); } +static bool file_memory_backend_get_pmem(Object *o, Error **errp) +{ + return MEMORY_BACKEND_FILE(o)->is_pmem; +} + +static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp) +{ + HostMemoryBackend *backend = MEMORY_BACKEND(o); + HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o); + + if (host_memory_backend_mr_inited(backend)) { + error_setg(errp, "cannot change property 'pmem' of %s '%s'", + object_get_typename(o), backend->id); + return; + } + + fb->is_pmem = value; +} + static void file_backend_unparent(Object *obj) { HostMemoryBackend *backend = MEMORY_BACKEND(obj); @@ -162,6 +183,9 @@ file_backend_class_init(ObjectClass *oc, void *data) file_memory_backend_get_align, file_memory_backend_set_align, NULL, NULL, &error_abort); + object_class_property_add_bool(oc, "pmem", + file_memory_backend_get_pmem, file_memory_backend_set_pmem, + &error_abort); } static void file_backend_instance_finalize(Object *o) diff --git a/docs/nvdimm.txt b/docs/nvdimm.txt index e903d8bb09..bcb2032672 100644 --- a/docs/nvdimm.txt +++ b/docs/nvdimm.txt @@ -153,3 +153,17 @@ guest NVDIMM region mapping structure. This unarmed flag indicates guest software that this vNVDIMM device contains a region that cannot accept persistent writes. In result, for example, the guest Linux NVDIMM driver, marks such vNVDIMM device as read-only. + +If the vNVDIMM backend is on the host persistent memory that can be +accessed in SNIA NVM Programming Model [1] (e.g., Intel NVDIMM), it's +suggested to set the 'pmem' option of memory-backend-file to 'on'. When +'pmem=on' and QEMU is built with libpmem [2] support (configured with +--enable-libpmem), QEMU will take necessary operations to guarantee +the persistence of its own writes to the vNVDIMM backend (e.g., in +vNVDIMM label emulation and live migration). + +References +---------- + +[1] SNIA NVM Programming Model: https://www.snia.org/sites/default/files/technical_work/final/NVMProgrammingModel_v1.2.pdf +[2] PMDK: http://pmem.io/pmdk/ diff --git a/exec.c b/exec.c index 537bf12412..3f3b61fb0a 100644 --- a/exec.c +++ b/exec.c @@ -99,6 +99,9 @@ static MemoryRegion io_mem_unassigned; */ #define RAM_RESIZEABLE (1 << 2) +/* RAM is backed by the persistent memory. */ +#define RAM_PMEM (1 << 3) + #endif #ifdef TARGET_PAGE_BITS_VARY @@ -2007,6 +2010,7 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, Error *local_err = NULL; int64_t file_size; bool share = flags & QEMU_RAM_SHARE; + bool is_pmem = flags & QEMU_RAM_PMEM; if (xen_enabled()) { error_setg(errp, "-mem-path not supported with Xen"); @@ -2043,7 +2047,8 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, new_block->mr = mr; new_block->used_length = size; new_block->max_length = size; - new_block->flags = share ? RAM_SHARED : 0; + new_block->flags = (share ? RAM_SHARED : 0) | + (is_pmem ? RAM_PMEM : 0); new_block->host = file_ram_alloc(new_block, size, fd, !file_size, errp); if (!new_block->host) { g_free(new_block); @@ -3749,6 +3754,11 @@ err: return ret; } +bool ramblock_is_pmem(RAMBlock *rb) +{ + return rb->flags & RAM_PMEM; +} + #endif void page_size_init(void) @@ -3847,3 +3857,4 @@ void mtree_print_dispatch(fprintf_function mon, void *f, } #endif + diff --git a/include/exec/memory.h b/include/exec/memory.h index 0fc9d23a48..b0b49a7a60 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -489,6 +489,7 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, #ifdef __linux__ #define QEMU_RAM_SHARE (1UL << 0) +#define QEMU_RAM_PMEM (1UL << 1) /** * memory_region_init_ram_from_file: Initialize RAM memory region with a @@ -504,6 +505,7 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, * @flags: specify properties of this memory region, which can be one or bit-or * of following values: * - QEMU_RAM_SHARE: memory must be mmaped with the MAP_SHARED flag + * - QEMU_RAM_PMEM: the backend @path is persistent memory * Other bits are ignored. * @path: the path in which to allocate the RAM. * @errp: pointer to Error*, to store an error if it happens. diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index b8b01d1eb9..f8d8614e4d 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -70,6 +70,8 @@ static inline unsigned long int ramblock_recv_bitmap_offset(void *host_addr, return host_addr_offset >> TARGET_PAGE_BITS; } +bool ramblock_is_pmem(RAMBlock *rb); + long qemu_getrampagesize(void); unsigned long last_ram_page(void); @@ -84,6 +86,7 @@ unsigned long last_ram_page(void); * @flags: specify the properties of the ram block, which can be one * or bit-or of following values * - QEMU_RAM_SHARE: mmap the back file or device with MAP_SHARED + * - QEMU_RAM_PMEM: the backend @mem_path or @fd is persistent memory * Other bits are ignored. * @mem_path or @fd: specify the back file or device * @errp: pointer to Error*, to store an error if it happens diff --git a/qemu-options.hx b/qemu-options.hx index 8ccd5dcaa6..62c7afe567 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3957,7 +3957,7 @@ property must be set. These objects are placed in the @table @option -@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off},discard-data=@var{on|off},merge=@var{on|off},dump=@var{on|off},prealloc=@var{on|off},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},align=@var{align} +@item -object memory-backend-file,id=@var{id},size=@var{size},mem-path=@var{dir},share=@var{on|off},discard-data=@var{on|off},merge=@var{on|off},dump=@var{on|off},prealloc=@var{on|off},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave},align=@var{align},pmem=@var{on|off} Creates a memory file backend object, which can be used to back the guest RAM with huge pages. @@ -4025,6 +4025,13 @@ requires an alignment different than the default one used by QEMU, eg the device DAX /dev/dax0.0 requires 2M alignment rather than 4K. In such cases, users can specify the required alignment via this option. +The @option{pmem} option specifies whether the backend store specified +by @option{mem-path} is on the persistent memory that can be accessed +in the SNIA NVM programming model (e.g. Intel NVDIMM). +If @option{pmem}=@var{on}, QEMU will take necessary operations to +guarantee the persistence of its own writes to @option{mem-path} +(e.g. in vNVDIMM label emulation and live migration). + @item -object memory-backend-ram,id=@var{id},merge=@var{on|off},dump=@var{on|off},share=@var{on|off},prealloc=@var{on|off},size=@var{size},host-nodes=@var{host-nodes},policy=@var{default|preferred|bind|interleave} Creates a memory backend object, which can be used to back the guest RAM.