diff options
-rw-r--r-- | migration.c | 11 | ||||
-rw-r--r-- | migration.h | 2 | ||||
-rw-r--r-- | vl.c | 19 |
3 files changed, 30 insertions, 2 deletions
diff --git a/migration.c b/migration.c index 57f2a52..748752e 100644 --- a/migration.c +++ b/migration.c @@ -107,6 +107,17 @@ void do_migrate_set_speed(Monitor *mon, const char *value) } +/* amount of nanoseconds we are willing to wait for migration to be down. + * the choice of nanoseconds is because it is the maximum resolution that + * get_clock() can achieve. It is an internal measure. All user-visible + * units must be in seconds */ +static uint64_t max_downtime = 30000000; + +uint64_t migrate_max_downtime(void) +{ + return max_downtime; +} + void do_info_migrate(Monitor *mon) { MigrationState *s = current_migration; diff --git a/migration.h b/migration.h index 696618d..0596f24 100644 --- a/migration.h +++ b/migration.h @@ -55,6 +55,8 @@ void do_migrate_cancel(Monitor *mon); void do_migrate_set_speed(Monitor *mon, const char *value); +uint64_t migrate_max_downtime(void); + void do_info_migrate(Monitor *mon); int exec_start_incoming_migration(const char *host_port); @@ -3188,7 +3188,6 @@ static int ram_save_block(QEMUFile *f) return found; } -static ram_addr_t ram_save_threshold = 10; static uint64_t bytes_transferred = 0; static ram_addr_t ram_save_remaining(void) @@ -3222,6 +3221,9 @@ uint64_t ram_bytes_total(void) static int ram_save_live(QEMUFile *f, int stage, void *opaque) { ram_addr_t addr; + uint64_t bytes_transferred_last; + double bwidth = 0; + uint64_t expected_time = 0; if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) { qemu_file_set_error(f); @@ -3241,6 +3243,9 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque) qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE); } + bytes_transferred_last = bytes_transferred; + bwidth = get_clock(); + while (!qemu_file_rate_limit(f)) { int ret; @@ -3250,6 +3255,14 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque) break; } + bwidth = get_clock() - bwidth; + bwidth = (bytes_transferred - bytes_transferred_last) / bwidth; + + /* if we haven't transferred anything this round, force expected_time to a + * a very high value, but without crashing */ + if (bwidth == 0) + bwidth = 0.000001; + /* try transferring iterative blocks of memory */ if (stage == 3) { @@ -3263,7 +3276,9 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque) qemu_put_be64(f, RAM_SAVE_FLAG_EOS); - return (stage == 2) && (ram_save_remaining() < ram_save_threshold); + expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth; + + return (stage == 2) && (expected_time <= migrate_max_downtime()); } static int ram_load_dead(QEMUFile *f, void *opaque) |