Hi, (Below is explenation about the bug to who does`nt familier) In the beggining I tried to make this code run with qemu_bh() but the result was performence catastrophic The reason is that the migration code just doesn`t built to run at such high granularity, for example sutff like: static ram_addr_t ram_save_remaining(void) { ram_addr_t addr; ram_addr_t count = 0; for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) { if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) count++; } return count; } That get called from ram_save_live(), were taking way too much time... (Just think that I tried to read each time small data, and run it at each time that main_loop_wait() finish (from qemu_bh_poll()) Then I thought ok - let`s add a timer that the bh code will run to me only once in a time - however the migration code already have timer that is set, so it like it make the most sense to use it... If anyone have any better idea how to solve this issue, I will be very happy to hear. Thanks. >From 2d9c25f1fee61f50cb130769c3779707a6ef90d9 Mon Sep 17 00:00:00 2001 From: Izik Eidus <ieidus@xxxxxxxxxx> Date: Mon, 5 Apr 2010 02:05:09 +0300 Subject: [PATCH] qemu-kvm: fix migration with large mem In cases of guests with large mem that have pages that all their bytes content are the same, we will spend alot of time reading the memory from the guest (is_dup_page()) It is happening beacuse ram_save_live() function have limit of how much we can send to the dest but not how much we read from it, and in cases we have many is_dup_page() hits, we might read huge amount of data without updating important stuff like the timers... The guest lose all its repsonsibility and have many softlock ups inside itself. this patch add limit on the size we can read from the guest each iteration. Thanks. Signed-off-by: Izik Eidus <ieidus@xxxxxxxxxx> --- vl.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/vl.c b/vl.c index d959fdb..777988d 100644 --- a/vl.c +++ b/vl.c @@ -174,6 +174,8 @@ int main(int argc, char **argv) #define DEFAULT_RAM_SIZE 128 +#define MAX_SAVE_BLOCK_READ 10 * 1024 * 1024 + #define MAX_VIRTIO_CONSOLES 1 static const char *data_dir; @@ -2854,6 +2856,7 @@ static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) uint64_t bytes_transferred_last; double bwidth = 0; uint64_t expected_time = 0; + int data_read = 0; if (stage < 0) { cpu_physical_memory_set_dirty_tracking(0); @@ -2883,10 +2886,11 @@ static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred_last = bytes_transferred; bwidth = qemu_get_clock_ns(rt_clock); - while (!qemu_file_rate_limit(f)) { + while (!qemu_file_rate_limit(f) && data_read < MAX_SAVE_BLOCK_READ) { int ret; ret = ram_save_block(f); + data_read += ret * TARGET_PAGE_SIZE; bytes_transferred += ret * TARGET_PAGE_SIZE; if (ret == 0) /* no more blocks */ break; -- 1.6.6.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html