Blame SOURCES/kvm-hostmem-file-add-the-pmem-option.patch

383d26
From 0b7c71b8b4afcbc92a9ef549d485c54da92204b3 Mon Sep 17 00:00:00 2001
383d26
From: "plai@redhat.com" <plai@redhat.com>
383d26
Date: Fri, 31 Aug 2018 16:25:56 +0200
383d26
Subject: [PATCH 14/29] hostmem-file: add the 'pmem' option
383d26
383d26
RH-Author: plai@redhat.com
383d26
Message-id: <1535732759-22481-7-git-send-email-plai@redhat.com>
383d26
Patchwork-id: 82007
383d26
O-Subject: [RHEL7.6 PATCH BZ 1539280 6/9] hostmem-file: add the 'pmem' option
383d26
Bugzilla: 1539280
383d26
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
383d26
RH-Acked-by: Pankaj Gupta <pagupta@redhat.com>
383d26
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
383d26
From: Junyan He <junyan.he@intel.com>
383d26
383d26
When QEMU emulates vNVDIMM labels and migrates vNVDIMM devices, it
383d26
needs to know whether the backend storage is a real persistent memory,
383d26
in order to decide whether special operations should be performed to
383d26
ensure the data persistence.
383d26
383d26
This boolean option 'pmem' allows users to specify whether the backend
383d26
storage of memory-backend-file is a real persistent memory. If
383d26
'pmem=on', QEMU will set the flag RAM_PMEM in the RAM block of the
383d26
corresponding memory region. If 'pmem' is set while lack of libpmem
383d26
support, a error is generated.
383d26
383d26
Signed-off-by: Junyan He <junyan.he@intel.com>
383d26
Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
383d26
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
383d26
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
383d26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
383d26
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
383d26
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
383d26
(cherry picked from commit a4de8552b2580adf6fa4874439217b65d3bdd88b)
383d26
Signed-off-by: Paul Lai <plai@redhat.com>
383d26
383d26
Resolved Conflicts:
383d26
	docs/nvdimm.txt
383d26
383d26
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
383d26
---
383d26
 backends/hostmem-file.c | 43 +++++++++++++++++++++++++++++++++++++++++--
383d26
 docs/nvdimm.txt         | 42 ++++++++++++++++++++++++++++++++++++++++++
383d26
 exec.c                  |  8 ++++++++
383d26
 include/exec/memory.h   |  4 ++++
383d26
 include/exec/ram_addr.h |  3 +++
383d26
 qemu-options.hx         |  7 +++++++
383d26
 6 files changed, 105 insertions(+), 2 deletions(-)
383d26
383d26
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
383d26
index 34c68bb..2476dcb 100644
383d26
--- a/backends/hostmem-file.c
383d26
+++ b/backends/hostmem-file.c
383d26
@@ -12,6 +12,7 @@
383d26
 #include "qemu/osdep.h"
383d26
 #include "qapi/error.h"
383d26
 #include "qemu-common.h"
383d26
+#include "qemu/error-report.h"
383d26
 #include "sysemu/hostmem.h"
383d26
 #include "sysemu/sysemu.h"
383d26
 #include "qom/object_interfaces.h"
383d26
@@ -31,9 +32,10 @@ typedef struct HostMemoryBackendFile HostMemoryBackendFile;
383d26
 struct HostMemoryBackendFile {
383d26
     HostMemoryBackend parent_obj;
383d26
 
383d26
-    bool discard_data;
383d26
     char *mem_path;
383d26
     uint64_t align;
383d26
+    bool discard_data;
383d26
+    bool is_pmem;
383d26
 };
383d26
 
383d26
 static void
383d26
@@ -59,7 +61,8 @@ file_backend_memory_alloc(HostMemoryBackend *backend, Error **errp)
383d26
         memory_region_init_ram_from_file(&backend->mr, OBJECT(backend),
383d26
                                  path,
383d26
                                  backend->size, fb->align,
383d26
-                                 backend->share ? RAM_SHARED : 0,
383d26
+                                 (backend->share ? RAM_SHARED : 0) |
383d26
+                                 (fb->is_pmem ? RAM_PMEM : 0),
383d26
                                  fb->mem_path, errp);
383d26
         g_free(path);
383d26
     }
383d26
@@ -131,6 +134,39 @@ static void file_memory_backend_set_align(Object *o, Visitor *v,
383d26
     error_propagate(errp, local_err);
383d26
 }
383d26
 
383d26
+static bool file_memory_backend_get_pmem(Object *o, Error **errp)
383d26
+{
383d26
+    return MEMORY_BACKEND_FILE(o)->is_pmem;
383d26
+}
383d26
+
383d26
+static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp)
383d26
+{
383d26
+    HostMemoryBackend *backend = MEMORY_BACKEND(o);
383d26
+    HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
383d26
+
383d26
+    if (host_memory_backend_mr_inited(backend)) {
383d26
+        error_setg(errp, "cannot change property 'pmem' of %s '%s'",
383d26
+                   object_get_typename(o),
383d26
+                   object_get_canonical_path_component(o));
383d26
+        return;
383d26
+    }
383d26
+
383d26
+#ifndef CONFIG_LIBPMEM
383d26
+    if (value) {
383d26
+        Error *local_err = NULL;
383d26
+        error_setg(&local_err,
383d26
+                   "Lack of libpmem support while setting the 'pmem=on'"
383d26
+                   " of %s '%s'. We can't ensure data persistence.",
383d26
+                   object_get_typename(o),
383d26
+                   object_get_canonical_path_component(o));
383d26
+        error_propagate(errp, local_err);
383d26
+        return;
383d26
+    }
383d26
+#endif
383d26
+
383d26
+    fb->is_pmem = value;
383d26
+}
383d26
+
383d26
 static void file_backend_unparent(Object *obj)
383d26
 {
383d26
     HostMemoryBackend *backend = MEMORY_BACKEND(obj);
383d26
@@ -162,6 +198,9 @@ file_backend_class_init(ObjectClass *oc, void *data)
383d26
         file_memory_backend_get_align,
383d26
         file_memory_backend_set_align,
383d26
         NULL, NULL, &error_abort);
383d26
+    object_class_property_add_bool(oc, "pmem",
383d26
+        file_memory_backend_get_pmem, file_memory_backend_set_pmem,
383d26
+        &error_abort);
383d26
 }
383d26
 
383d26
 static void file_backend_instance_finalize(Object *o)
383d26
diff --git a/docs/nvdimm.txt b/docs/nvdimm.txt
383d26
index e903d8b..5f158a6 100644
383d26
--- a/docs/nvdimm.txt
383d26
+++ b/docs/nvdimm.txt
383d26
@@ -153,3 +153,45 @@ guest NVDIMM region mapping structure.  This unarmed flag indicates
383d26
 guest software that this vNVDIMM device contains a region that cannot
383d26
 accept persistent writes. In result, for example, the guest Linux
383d26
 NVDIMM driver, marks such vNVDIMM device as read-only.
383d26
+
383d26
+NVDIMM Persistence
383d26
+------------------
383d26
+
383d26
+ACPI 6.2 Errata A added support for a new Platform Capabilities Structure
383d26
+which allows the platform to communicate what features it supports related to
383d26
+NVDIMM data persistence.  Users can provide a persistence value to a guest via
383d26
+the optional "nvdimm-persistence" machine command line option:
383d26
+
383d26
+    -machine pc,accel=kvm,nvdimm,nvdimm-persistence=cpu
383d26
+
383d26
+There are currently two valid values for this option:
383d26
+
383d26
+"mem-ctrl" - The platform supports flushing dirty data from the memory
383d26
+             controller to the NVDIMMs in the event of power loss.
383d26
+
383d26
+"cpu"      - The platform supports flushing dirty data from the CPU cache to
383d26
+             the NVDIMMs in the event of power loss.  This implies that the
383d26
+             platform also supports flushing dirty data through the memory
383d26
+             controller on power loss.
383d26
+
383d26
+If the vNVDIMM backend is in host persistent memory that can be accessed in
383d26
+SNIA NVM Programming Model [1] (e.g., Intel NVDIMM), it's suggested to set
383d26
+the 'pmem' option of memory-backend-file to 'on'. When 'pmem' is 'on' and QEMU
383d26
+is built with libpmem [2] support (configured with --enable-libpmem), QEMU
383d26
+will take necessary operations to guarantee the persistence of its own writes
383d26
+to the vNVDIMM backend(e.g., in vNVDIMM label emulation and live migration).
383d26
+If 'pmem' is 'on' while there is no libpmem support, qemu will exit and report
383d26
+a "lack of libpmem support" message to ensure the persistence is available.
383d26
+For example, if we want to ensure the persistence for some backend file,
383d26
+use the QEMU command line:
383d26
+
383d26
+    -object memory-backend-file,id=nv_mem,mem-path=/XXX/yyy,size=4G,pmem=on
383d26
+
383d26
+References
383d26
+----------
383d26
+
383d26
+[1] NVM Programming Model (NPM)
383d26
+	Version 1.2
383d26
+    https://www.snia.org/sites/default/files/technical_work/final/NVMProgrammingModel_v1.2.pdf
383d26
+[2] Persistent Memory Development Kit (PMDK), formerly known as NVML project, home page:
383d26
+    http://pmem.io/pmdk/
383d26
diff --git a/exec.c b/exec.c
383d26
index 295142b..c670185 100644
383d26
--- a/exec.c
383d26
+++ b/exec.c
383d26
@@ -2045,6 +2045,9 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
383d26
     Error *local_err = NULL;
383d26
     int64_t file_size;
383d26
 
383d26
+    /* Just support these ram flags by now. */
383d26
+    assert((ram_flags & ~(RAM_SHARED | RAM_PMEM)) == 0);
383d26
+
383d26
     if (xen_enabled()) {
383d26
         error_setg(errp, "-mem-path not supported with Xen");
383d26
         return NULL;
383d26
@@ -3863,6 +3866,11 @@ err:
383d26
     return ret;
383d26
 }
383d26
 
383d26
+bool ramblock_is_pmem(RAMBlock *rb)
383d26
+{
383d26
+    return rb->flags & RAM_PMEM;
383d26
+}
383d26
+
383d26
 #endif
383d26
 
383d26
 void page_size_init(void)
383d26
diff --git a/include/exec/memory.h b/include/exec/memory.h
383d26
index b3abe61..fd2c574 100644
383d26
--- a/include/exec/memory.h
383d26
+++ b/include/exec/memory.h
383d26
@@ -122,6 +122,9 @@ typedef struct IOMMUNotifier IOMMUNotifier;
383d26
 /* RAM can be migrated */
383d26
 #define RAM_MIGRATABLE (1 << 4)
383d26
 
383d26
+/* RAM is a persistent kind memory */
383d26
+#define RAM_PMEM (1 << 5)
383d26
+
383d26
 static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
383d26
                                        IOMMUNotifierFlag flags,
383d26
                                        hwaddr start, hwaddr end)
383d26
@@ -541,6 +544,7 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr,
383d26
  *         (getpagesize()) will be used.
383d26
  * @ram_flags: Memory region features:
383d26
  *             - RAM_SHARED: memory must be mmaped with the MAP_SHARED flag
383d26
+ *             - RAM_PMEM: the memory is persistent memory
383d26
  *             Other bits are ignored now.
383d26
  * @path: the path in which to allocate the RAM.
383d26
  * @errp: pointer to Error*, to store an error if it happens.
383d26
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
383d26
index 67e163e..922305d 100644
383d26
--- a/include/exec/ram_addr.h
383d26
+++ b/include/exec/ram_addr.h
383d26
@@ -70,6 +70,8 @@ static inline unsigned long int ramblock_recv_bitmap_offset(void *host_addr,
383d26
     return host_addr_offset >> TARGET_PAGE_BITS;
383d26
 }
383d26
 
383d26
+bool ramblock_is_pmem(RAMBlock *rb);
383d26
+
383d26
 long qemu_getrampagesize(void);
383d26
 unsigned long last_ram_page(void);
383d26
 
383d26
@@ -84,6 +86,7 @@ unsigned long last_ram_page(void);
383d26
  *  @ram_flags: specify the properties of the ram block, which can be one
383d26
  *              or bit-or of following values
383d26
  *              - RAM_SHARED: mmap the backing file or device with MAP_SHARED
383d26
+ *              - RAM_PMEM: the backend @mem_path or @fd is persistent memory
383d26
  *              Other bits are ignored.
383d26
  *  @mem_path or @fd: specify the backing file or device
383d26
  *  @errp: pointer to Error*, to store an error if it happens
383d26
diff --git a/qemu-options.hx b/qemu-options.hx
383d26
index 4271cd3..5c58760 100644
383d26
--- a/qemu-options.hx
383d26
+++ b/qemu-options.hx
383d26
@@ -4045,6 +4045,13 @@ requires an alignment different than the default one used by QEMU, eg
383d26
 the device DAX /dev/dax0.0 requires 2M alignment rather than 4K. In
383d26
 such cases, users can specify the required alignment via this option.
383d26
 
383d26
+The @option{pmem} option specifies whether the backing file specified
383d26
+by @option{mem-path} is in host persistent memory that can be accessed
383d26
+using the SNIA NVM programming model (e.g. Intel NVDIMM).
383d26
+If @option{pmem} is set to 'on', QEMU will take necessary operations to
383d26
+guarantee the persistence of its own writes to @option{mem-path}
383d26
+(e.g. in vNVDIMM label emulation and live migration).
383d26
+
383d26
 @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}
383d26
 
383d26
 Creates a memory backend object, which can be used to back the guest RAM.
383d26
-- 
383d26
1.8.3.1
383d26