WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [qemu-xen-unstable] fix HVM log dirty issue
From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
Date: Fri, 4 Sep 2009 10:05:02 -0700
Delivery-date: Fri, 04 Sep 2009 10:05:07 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [qemu-xen-unstable] fix HVM log dirty issue, Ian Jackson <=