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

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