Patchwork [PATCHv5,06/10] migration: search for zero instead of dup pages

login
register
mail settings
Submitter Peter Lieven
Date April 8, 2013, 9:25 a.m.
Message ID <20A68F8D-6ED4-4ABD-AC65-4E9F26631F93@kamp.de>
Download mbox | patch
Permalink /patch/234614/
State New
Headers show

Comments

Peter Lieven - April 8, 2013, 9:25 a.m.
Am 08.04.2013 um 10:38 schrieb Paolo Bonzini <pbonzini@redhat.com>:

> Il 06/04/2013 00:06, Peter Lieven ha scritto:
>>>> I think we should MADV_DONTNEED it.
>> i have to correct myself, on Linux it seems that MADV_DONTNEED guarantees that
>> subsequent reads will return a zero filled page.
>> 
>> If I am right with that we could MADV_DONTNEED the memory on startup and keep
>> not sending zero pages in bulk stage if we are running under Linux. Am I right with that?
> 
> Actually we can use mmap+munmap to allocate a well-aligned, always zero
> block for the RAM.

like this?
Paolo Bonzini - April 8, 2013, 10:33 a.m.
Il 08/04/2013 11:25, Peter Lieven ha scritto:
>> > Actually we can use mmap+munmap to allocate a well-aligned, always zero
>> > block for the RAM.
> like this?

This doesn't align it.  I'll send a patch shortly.

Paolo

Patch

diff --git a/exec.c b/exec.c
index 786987a..dfd1ad3 100644
--- a/exec.c
+++ b/exec.c
@@ -1048,27 +1048,31 @@  ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
         new_block->host = host;
         new_block->flags |= RAM_PREALLOC_MASK;
     } else {
-        if (mem_path) {
+        if (xen_enabled()) {
+            xen_ram_alloc(new_block->offset, size, mr);
+            memory_try_enable_merging(new_block->host, size);
+        } else {
+            if (mem_path) {
 #if defined (__linux__) && !defined(TARGET_S390X)
-            new_block->host = file_ram_alloc(new_block, size, mem_path);
-            if (!new_block->host) {
-                new_block->host = qemu_vmalloc(size);
-                memory_try_enable_merging(new_block->host, size);
-            }
+                new_block->host = file_ram_alloc(new_block, size, mem_path);
 #else
-            fprintf(stderr, "-mem-path option unsupported\n");
-            exit(1);
+                fprintf(stderr, "-mem-path option unsupported\n");
+                exit(1);
 #endif
-        } else {
-            if (xen_enabled()) {
-                xen_ram_alloc(new_block->offset, size, mr);
-            } else if (kvm_enabled()) {
+            } 
+            if (!new_block->host && kvm_enabled()) {
                 /* some s390/kvm configurations have special constraints */
                 new_block->host = kvm_vmalloc(size);
-            } else {
-                new_block->host = qemu_vmalloc(size);
             }
-            memory_try_enable_merging(new_block->host, size);
+            if (!new_block->host) {
+                new_block->host = mmap(0, size, PROT_READ | PROT_WRITE, 
+                                       MAP_ANONYMOUS |  MAP_PRIVATE, -1, 0);
+                if (new_block->host == MAP_FAILED) {
+                    fprintf(stderr,"qemu_ram_alloc: can't mmap RAM pages %d\n",errno);
+                    exit(1);
+                }
+                memory_try_enable_merging(new_block->host, size);
+            }
         }
     }
     new_block->length = size;
@@ -1142,25 +1146,19 @@  void qemu_ram_free(ram_addr_t addr)
                 ;
             } else if (mem_path) {
 #if defined (__linux__) && !defined(TARGET_S390X)
+                munmap(block->host, block->length);
                 if (block->fd) {
-                    munmap(block->host, block->length);
                     close(block->fd);
-                } else {
-                    qemu_vfree(block->host);
                 }
 #else
                 abort();
 #endif
             } else {
-#if defined(TARGET_S390X) && defined(CONFIG_KVM)
-                munmap(block->host, block->length);
-#else
                 if (xen_enabled()) {
                     xen_invalidate_map_cache_entry(block->host);
                 } else {
-                    qemu_vfree(block->host);
+                    munmap(block->host, block->length);
                 }
-#endif
             }
             g_free(block);
             break;
diff --git a/kvm-all.c b/kvm-all.c
index 9b433d3..90be8e3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1742,7 +1742,7 @@  void *kvm_vmalloc(ram_addr_t size)
         return mem;
     }
 #endif
-    return qemu_vmalloc(size);
+    return NULL;
 }
 
 void kvm_setup_guest_memory(void *start, size_t size)