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 <iei...@redhat.com>
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 <iei...@redhat.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to