[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