summaryrefslogtreecommitdiff
path: root/vl.c
diff options
context:
space:
mode:
Diffstat (limited to 'vl.c')
-rw-r--r--vl.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/vl.c b/vl.c
index 1301f9fbb7..3242c230ea 100644
--- a/vl.c
+++ b/vl.c
@@ -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)