]> xenbits.xensource.com Git - qemu-xen-4.1-testing.git/commitdiff
[stubdom] fix the crash of HVM live migration with intensive disk access
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 4 Sep 2009 15:10:46 +0000 (16:10 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 4 Sep 2009 15:10:46 +0000 (16:10 +0100)
Intensive disk access, e.g. sum of big file, during HVM live migration would
cause guest error even file system crash. Guest dmesg said
"attempt to access beyond end of device
hda1: rw=0, want=10232032112, limit=10474317"

Current map cache used by qemu dma doesn't mark the page dirty, so that these
pages(probably holding DMA data struct) are not transferred in the last
iteration during live migration.

This patch fixes it, and also merges the qemu's original dirty bitmap used by
other devices such as vga.

Signed-Off-By: Zhai Edwin <edwin.zhai@intel.com>
cpu-all.h
i386-dm/exec-dm.c

index c5c3ef2341f62d92d6edbe49e14acbeaff5011f7..90231277dbd7dbfcd8bc81888fde6827a4507563 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -975,6 +975,16 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
 static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
 {
     phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
+
+#ifndef CONFIG_STUBDOM
+    if (logdirty_bitmap != NULL) {
+        addr >>= TARGET_PAGE_BITS;
+        if (addr / 8 < logdirty_bitmap_size) {
+            logdirty_bitmap[addr / HOST_LONG_BITS]
+                |= 1UL << addr % HOST_LONG_BITS;
+        }
+    }
+#endif
 }
 
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
index b8af55a3f59d9139267971df2766da6ecd8b8020..4fc26cde96efc58bd9b4be08be106fea958e9422 100644 (file)
@@ -805,6 +805,24 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
     unsigned long l = MCACHE_BUCKET_SIZE - (addr & (MCACHE_BUCKET_SIZE-1));
     if ((*plen) > l)
         *plen = l;
+#endif
+#ifndef CONFIG_STUBDOM
+    if (logdirty_bitmap != NULL) {
+        /* Record that we have dirtied this frame */
+        unsigned long pfn = addr >> TARGET_PAGE_BITS;
+        do {
+            if (pfn / 8 >= logdirty_bitmap_size) {
+                fprintf(logfile, "dirtying pfn %lx >= bitmap "
+                        "size %lx\n", pfn, logdirty_bitmap_size * 8);
+            } else {
+                logdirty_bitmap[pfn / HOST_LONG_BITS]
+                    |= 1UL << pfn % HOST_LONG_BITS;
+            }
+
+            pfn++;
+        } while ( (pfn << TARGET_PAGE_BITS) < addr + *plen );
+
+    }
 #endif
     return qemu_map_cache(addr, 1);
 }