When the total sent page size is larger than max_factor times of the size of guest OS's memory, stop the iteration. The default value of max_factor is 3.
This is similar to XEN. Signed-off-by: Wen Congyang --- arch_init.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/arch_init.c b/arch_init.c index 4486925..67e90f8 100644 --- a/arch_init.c +++ b/arch_init.c @@ -212,6 +212,14 @@ uint64_t ram_bytes_total(void) return total; } +static uint64_t ram_blocks_total(void) +{ + return ram_bytes_total() / TARGET_PAGE_SIZE; +} + +static uint64_t blocks_transferred = 0; +static int max_factor = 3; + int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) { ram_addr_t addr; @@ -234,6 +242,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_transferred = 0; last_block = NULL; last_offset = 0; + blocks_transferred = 0; /* Make sure all dirty bits are set */ QLIST_FOREACH(block, &ram_list.blocks, next) { @@ -266,6 +275,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) bytes_sent = ram_save_block(f); bytes_transferred += bytes_sent; + blocks_transferred += !!bytes_sent; if (bytes_sent == 0) { /* no more blocks */ break; } @@ -295,7 +305,8 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth; - return (stage == 2) && (expected_time <= migrate_max_downtime()); + return (stage == 2) && ((expected_time <= migrate_max_downtime()) + || (blocks_transferred > ram_blocks_total() * max_factor)); } static inline void *host_from_stream_offset(QEMUFile *f, -- 1.7.1