@@ -426,6 +426,8 @@ static void migration_bitmap_sync(void)
* 0 means no dirty pages
*/
+static uint64_t complete_rounds;
+
static int ram_save_block(QEMUFile *f, bool last_stage)
{
RAMBlock *block = last_seen_block;
@@ -451,6 +453,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
if (!block) {
block = QTAILQ_FIRST(&ram_list.blocks);
complete_round = true;
+ if (!complete_rounds) {
+ error_report("ram_save_block: finished bulk ram migration");
+ }
+ complete_rounds++;
}
} else {
uint8_t *p;
@@ -463,10 +469,17 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
bytes_sent = -1;
if (is_dup_page(p)) {
acct_info.dup_pages++;
- bytes_sent = save_block_hdr(f, block, offset, cont,
+ /* we can skip transferring zero pages in the first round because
+ memory is unmapped (reads as zero) at the target anyway or initialized
+ to zero in case of mem-prealloc. */
+ if (complete_rounds || *p) {
+ bytes_sent = save_block_hdr(f, block, offset, cont,
RAM_SAVE_FLAG_COMPRESS);
- qemu_put_byte(f, *p);
- bytes_sent += 1;
+ qemu_put_byte(f, *p);
+ bytes_sent += 1;
+ } else {
+ bytes_sent = 1;
+ }
} else if (migrate_use_xbzrle()) {
current_addr = block->offset + offset;
bytes_sent = save_xbzrle_page(f, p, current_addr, block,
@@ -569,6 +582,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
qemu_mutex_lock_ramlist();
bytes_transferred = 0;
+ complete_rounds = 0;
reset_ram_globals();
if (migrate_use_xbzrle()) {