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
|