qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/5] memory: Add RAM_NONPERSISTENT flag


From: Eduardo Habkost
Subject: [Qemu-devel] [PATCH 3/5] memory: Add RAM_NONPERSISTENT flag
Date: Wed, 14 Jun 2017 17:29:58 -0300

The new flag will make qemu_ram_free() discard the contents of the
block.  It will be used to let QEMU be configured to avoid flushing file
contents to disk when exiting.  As MADV_REMOVE is not always supported,
the new code will try MADV_NOTNEEDED in case MADV_REMOVE fails.

The new flag will also indicate that ram_block_discard_range() can use
MADV_REMOVE when discarding memory pages.  I have considered calling
MADV_REMOVE unconditionally (as destroying the RAM contents seems to be
OK every time ram_block_discard_range() is called), but for safety I
decided to restrict the new code to blocks having RAM_NONPERSISTENT set.

Signed-off-by: Eduardo Habkost <address@hidden>
---
 exec.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 585d6ed6d7..a6e9ed4ece 100644
--- a/exec.c
+++ b/exec.c
@@ -102,6 +102,11 @@ static MemoryRegion io_mem_unassigned;
  */
 #define RAM_RESIZEABLE (1 << 2)
 
+/* RAMBlock contents are not persistent, and we can discard memory contents
+ * when freeing the memory block.
+ */
+#define RAM_NONPERSISTENT (1 << 3)
+
 #endif
 
 #ifdef TARGET_PAGE_BITS_VARY
@@ -2061,6 +2066,10 @@ void qemu_ram_free(RAMBlock *block)
         ram_block_notify_remove(block->host, block->max_length);
     }
 
+    if (block->flags & RAM_NONPERSISTENT) {
+        ram_block_discard_range(block, 0, block->max_length);
+    }
+
     qemu_mutex_lock_ramlist();
     QLIST_REMOVE_RCU(block, next);
     ram_list.mru_block = NULL;
@@ -3537,7 +3546,13 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t 
start, size_t length)
             /* Note: We need the madvise MADV_DONTNEED behaviour of definitely
              * freeing the page.
              */
-            ret = madvise(host_startaddr, length, MADV_DONTNEED);
+            if (rb->flags & RAM_NONPERSISTENT) {
+                ret = madvise(host_startaddr, length, MADV_REMOVE);
+            }
+            /* Fallback to MADV_DONTNEED if MADV_REMOVE fails */
+            if (ret || !(rb->flags & RAM_NONPERSISTENT)) {
+                ret = madvise(host_startaddr, length, MADV_DONTNEED);
+            }
 #endif
         } else {
             /* Huge page case  - unfortunately it can't do DONTNEED, but
-- 
2.11.0.259.g40922b1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]