[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |