fix migration with big mem guests
PATCH 1/1 fix migration with big mem guests
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.
Quoted 1 line
From
2d9c25f1fee61f50cb130769c3779707a6ef90d9Mon Sep 17 00:00:00 2001
From: Izik Eidus <[email protected]>
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.
--- vl.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
vl.c +5 -1
@@ -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 1static 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 ;
Signature · 1 line
1.6.6.1
Quoted 27 lines · Izik Eidus
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 catastrophicThe reason is that the migration code just doesn`t built to run at such high granularity, for example sutff like:
static
ram_addr_tram_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 thatmain_loop_wait()finish (fromqemu_bh_poll())
Quoted 6 lines
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.
Izik,
Looks good to me. Please send to qemu-devel.
Quoted 73 lines
Thanks.
Quoted 1 line
From
2d9c25f1fee61f50cb130769c3779707a6ef90d9Mon Sep 17 00:00:00 2001From: Izik Eidus <[email protected]>
Date: Mon, 5 Apr 2010 02:05:09 +0300
Subject: [PATCH] qemu-kvm: fix migration with large memIn 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 manyis_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 <[email protected]>--- vl.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)vl.c +5
-1@@ -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 1static 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 ;Signature · 6 lines
1.6.6.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html