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

[Xen-changelog] [qemu-xen-unstable] fix HVM log dirty issue



commit 60dbe1d43827cf9a57b619a8736da2319489d432
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Date:   Fri Sep 4 16:25:35 2009 +0100

    fix HVM log dirty issue
    
    These patches fix some issues for HVM log dirty in qemu:
    * Add necessary logging dirty in qemu to avoid guest error with
    intensive disk access when live migration
    * Take place of shared memory between qemu and migration tools by new
    added hypercall, which is clean and simple
    
    Signed-Off-By: Zhai, Edwin <edwin.zhai@xxxxxxxxx>
    
    Also revert commit 32710fbdc75e055f73a63d246737ce615b9109e9.
      "[stubdom] fix the crash of HVM live migration with intensive disk access"
     as this is the proper fix.   -iwj
---
 cpu-all.h         |   14 ++----
 i386-dm/exec-dm.c |   59 ++++++++----------------
 xen-config-host.h |    3 +-
 xenstore.c        |  130 +++++++++++-----------------------------------------
 4 files changed, 53 insertions(+), 153 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 9023127..60e0ac3 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -972,20 +972,14 @@ static inline int 
cpu_physical_memory_get_dirty(ram_addr_t addr,
     return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
 }
 
+#ifdef CONFIG_DM
+void cpu_physical_memory_set_dirty(ram_addr_t addr);
+#else
 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
 }
+#endif
 
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                                      int dirty_flags);
diff --git a/i386-dm/exec-dm.c b/i386-dm/exec-dm.c
index 4fc26cd..6ee095e 100644
--- a/i386-dm/exec-dm.c
+++ b/i386-dm/exec-dm.c
@@ -359,6 +359,14 @@ void cpu_unregister_io_memory(int io_table_address)
     io_mem_opaque[io_index] = NULL;
 }
 
+void cpu_physical_memory_set_dirty(ram_addr_t addr)
+{
+    phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
+
+    if (xen_logdirty_enable)
+        xc_hvm_modified_memory(xc_handle, domid, addr >> TARGET_PAGE_BITS, 1);
+}
+
 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
 {
     return io_mem_write[io_index >> IO_MEM_SHIFT];
@@ -453,8 +461,7 @@ void unregister_iomem(target_phys_addr_t start)
 }
 
 
-unsigned long *logdirty_bitmap;
-unsigned long logdirty_bitmap_size;
+unsigned int xen_logdirty_enable = 0;
 
 /*
  * Replace the standard byte memcpy with a word memcpy for appropriately sized
@@ -557,19 +564,13 @@ void cpu_physical_memory_rw(target_phys_addr_t _addr, 
uint8_t *buf,
             } else if ((ptr = phys_ram_addr(addr)) != NULL) {
                 /* Writing to RAM */
                 memcpy_words(ptr, buf, l);
-#ifndef CONFIG_STUBDOM
-                if (logdirty_bitmap != NULL) {
-                    /* Record that we have dirtied this frame */
-                    unsigned long pfn = addr >> TARGET_PAGE_BITS;
-                    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;
-                    }
-                }
-#endif
+
+                if (xen_logdirty_enable)
+                    xc_hvm_modified_memory(xc_handle,
+                        domid,
+                        addr >> TARGET_PAGE_BITS,
+                        ((addr + l + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
+                        - (addr >> TARGET_PAGE_BITS));
 #ifdef __ia64__
                 sync_icache(ptr, l);
 #endif 
@@ -605,13 +606,6 @@ void cpu_physical_memory_rw(target_phys_addr_t _addr, 
uint8_t *buf,
         addr += l;
     }
 
-#ifdef CONFIG_STUBDOM
-    if (logdirty_bitmap != NULL)
-        xc_hvm_modified_memory(xc_handle, domid, _addr >> TARGET_PAGE_BITS,
-                ((_addr + _len + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
-                    - (_addr >> TARGET_PAGE_BITS));
-#endif
-
     mapcache_unlock();
 }
 #endif
@@ -806,24 +800,11 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
     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;
-            }
+    if (xen_logdirty_enable)
+        xc_hvm_modified_memory(xc_handle, domid, addr >> TARGET_PAGE_BITS,
+                ((addr + l + TARGET_PAGE_SIZE - 1) >> TARGET_PAGE_BITS)
+                    - (addr >> TARGET_PAGE_BITS));
 
-            pfn++;
-        } while ( (pfn << TARGET_PAGE_BITS) < addr + *plen );
-
-    }
-#endif
     return qemu_map_cache(addr, 1);
 }
 
diff --git a/xen-config-host.h b/xen-config-host.h
index f34e76b..3a04df9 100644
--- a/xen-config-host.h
+++ b/xen-config-host.h
@@ -39,8 +39,7 @@ struct CharDriverState;
 void xenstore_store_serial_port_info(int i, struct CharDriverState *chr,
                                     const char *devname);
 
-extern unsigned long *logdirty_bitmap;
-extern unsigned long logdirty_bitmap_size;
+extern unsigned int xen_logdirty_enable;
 
 #ifdef CONFIG_STUBDOM
 #undef HAVE_IOVEC
diff --git a/xenstore.c b/xenstore.c
index bdc25c3..e091259 100644
--- a/xenstore.c
+++ b/xenstore.c
@@ -13,13 +13,6 @@
 
 #include "block_int.h"
 #include <unistd.h>
-#ifndef CONFIG_STUBDOM
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <assert.h>
 
 #include "exec-all.h"
@@ -597,8 +590,8 @@ void xenstore_parse_domain_config(int hvm_domid)
 #endif
 
 
-    /* Set a watch for log-dirty requests from the migration tools */
-    if (pasprintf(&buf, "/local/domain/0/device-model/%u/logdirty/next-active",
+    /* Set a watch for log-dirty commands from the migration tools */
+    if (pasprintf(&buf, "/local/domain/0/device-model/%u/logdirty/cmd",
                   domid) != -1) {
         xs_watch(xsh, buf, "logdirty");
         fprintf(logfile, "Watching %s\n", buf);
@@ -689,111 +682,44 @@ int xenstore_fd(void)
 static void xenstore_process_logdirty_event(void)
 {
     char *act;
-    static char *active_path = NULL;
-    static char *next_active_path = NULL;
-    static char *seg = NULL;
+    char *ret_path = NULL;
+    char *cmd_path = NULL;
     unsigned int len;
-    int i;
-
-    if (!seg) {
-        char *path = NULL, *key_ascii, key_terminated[17] = {0,};
-        key_t key;
-        int shmid;
-
-        /* Find and map the shared memory segment for log-dirty bitmaps */
-        if (pasprintf(&path, 
-                      "/local/domain/0/device-model/%u/logdirty/key", 
-                      domid) == -1) {
-            fprintf(logfile, "Log-dirty: out of memory\n");
-            exit(1);
-        }
-        
-        key_ascii = xs_read(xsh, XBT_NULL, path, &len);
-        free(path);
-
-        if (!key_ascii) 
-            /* No key yet: wait for the next watch */
-            return;
 
-#ifdef CONFIG_STUBDOM
-        /* We pass the writes to hypervisor */
-        seg = (void*)1;
-#else
-        strncpy(key_terminated, key_ascii, 16);
-        free(key_ascii);
-        key = (key_t) strtoull(key_terminated, NULL, 16);
-
-        /* Figure out how bit the log-dirty bitmaps are */
-        logdirty_bitmap_size = xc_memory_op(xc_handle, 
-                                            XENMEM_maximum_gpfn, &domid) + 1;
-        logdirty_bitmap_size = ((logdirty_bitmap_size + HOST_LONG_BITS - 1)
-                                / HOST_LONG_BITS); /* longs */
-        logdirty_bitmap_size *= sizeof (unsigned long); /* bytes */
-
-        /* Map the shared-memory segment */
-        fprintf(logfile, "%s: key=%16.16llx size=%lu\n", __FUNCTION__,
-                (unsigned long long)key, logdirty_bitmap_size);
-        shmid = shmget(key, 2 * logdirty_bitmap_size, S_IRUSR|S_IWUSR);
-        if (shmid == -1) {
-            fprintf(logfile, "Log-dirty: shmget failed: segment %16.16llx "
-                    "(%s)\n", (unsigned long long)key, strerror(errno));
-            exit(1);
-        }
-
-        seg = shmat(shmid, NULL, 0);
-        if (seg == (void *)-1) {
-            fprintf(logfile, "Log-dirty: shmat failed: segment %16.16llx "
-                    "(%s)\n", (unsigned long long)key, strerror(errno));
-            exit(1);
-        }
-
-        fprintf(logfile, "Log-dirty: mapped segment at %p\n", seg);
-
-        /* Double-check that the bitmaps are the size we expect */
-        if (logdirty_bitmap_size != *(uint32_t *)seg) {
-            fprintf(logfile, "Log-dirty: got %u, calc %lu\n", 
-                    *(uint32_t *)seg, logdirty_bitmap_size);
-            /* Stale key: wait for next watch */
-            shmdt(seg);
-            seg = NULL;
-            return;
-        }
-#endif
-
-        /* Remember the paths for the next-active and active entries */
-        if (pasprintf(&active_path, 
-                      "/local/domain/0/device-model/%u/logdirty/active",
-                      domid) == -1) {
-            fprintf(logfile, "Log-dirty: out of memory\n");
-            exit(1);
-        }
-        if (pasprintf(&next_active_path, 
-                      "/local/domain/0/device-model/%u/logdirty/next-active",
-                      domid) == -1) {
-            fprintf(logfile, "Log-dirty: out of memory\n");
-            exit(1);
-        }
+    /* Remember the paths for the command and response entries */
+    if (pasprintf(&ret_path,
+                "/local/domain/0/device-model/%u/logdirty/ret",
+                domid) == -1) {
+        fprintf(logfile, "Log-dirty: out of memory\n");
+        exit(1);
+    }
+    if (pasprintf(&cmd_path,
+                "/local/domain/0/device-model/%u/logdirty/cmd",
+                domid) == -1) {
+        fprintf(logfile, "Log-dirty: out of memory\n");
+        exit(1);
     }
 
-    fprintf(logfile, "Triggered log-dirty buffer switch\n");
     
     /* Read the required active buffer from the store */
-    act = xs_read(xsh, XBT_NULL, next_active_path, &len);
+    act = xs_read(xsh, XBT_NULL, cmd_path, &len);
     if (!act) {
-        fprintf(logfile, "Log-dirty: can't read next-active\n");
-        exit(1);
+        fprintf(logfile, "Log-dirty: no command yet.\n");
+        return;
     }
+    fprintf(logfile, "Log-dirty command %s\n", act);
 
-    /* Switch buffers */
-    i = act[0] - '0';
-    if (i != 0 && i != 1) {
-        fprintf(logfile, "Log-dirty: bad next-active entry: %s\n", act);
+    if (!strcmp(act, "enable")) {
+        xen_logdirty_enable = 1;
+    } else if (!strcmp(act, "disable")) {
+        xen_logdirty_enable = 0;
+    } else {
+        fprintf(logfile, "Log-dirty: bad log-dirty command: %s\n", act);
         exit(1);
     }
-    logdirty_bitmap = (unsigned long *)(seg + i * logdirty_bitmap_size);
 
-    /* Ack that we've switched */
-    xs_write(xsh, XBT_NULL, active_path, act, len);
+    /* Ack that we've service the command */
+    xs_write(xsh, XBT_NULL, ret_path, act, len);
     free(act);
 }
 
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.