Skip to contentSkip to conversation

Avoid loading ram pages that are all zeroes

PATCH New Avi Kivity 1 participant 1 message Dec 14, 2008

lore
Share & tools
lore

Avi Kivity

author
#0 lore raw

PATCH 1/1 Avoid loading ram pages that are all zeroes

Restoring or migrating zero pages causes unnecessary allocation of memory. We can avoid this by dropping the loaded page instead of memset()ing it.

vl.c +17 -0
index 7b58605..42e97c9 100644
@@ -3019,6 +3019,19 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 /***********************************************************/
 /* ram save/restore */
 
+static void drop_page(uint8_t *page)
+{
+    if (TARGET_PAGE_SIZE < getpagesize())
+        return;
+#ifdef CONFIG_KVM
+    if (kvm_enabled() && !kvm_has_sync_mmu())
+        return;
+#endif
+#ifdef MADV_DONTNEED
+    madvise(page, TARGET_PAGE_SIZE, MADV_DONTNEED);
+#endif
+}
+
 static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
 {
     int v;
@@ -3032,6 +3045,8 @@ static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
     case 1:
         v = qemu_get_byte(f);
         memset(buf, v, len);
+        if (v == 0)
+            drop_page(buf);
         break;
     default:
         return -EINVAL;
@@ -3289,6 +3304,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
         if (flags & RAM_SAVE_FLAG_COMPRESS) {
             uint8_t ch = qemu_get_byte(f);
             memset(phys_ram_base + addr, ch, TARGET_PAGE_SIZE);
+            if (ch == 0)
+                drop_page(phys_ram_base + addr);
         } else if (flags & RAM_SAVE_FLAG_PAGE)
             qemu_get_buffer(f, phys_ram_base + addr, TARGET_PAGE_SIZE);
     } while (!(flags & RAM_SAVE_FLAG_EOS));