s->threshold_size = 0;
s->switchover_acked = false;
s->rdma_migration = false;
+
/*
- * set mig_stats memory to zero for a new migration
+ * set mig_stats memory to zero for a new migration.. except the
+ * iteration counter, which we want to make sure it returns 1 for the
+ * first iteration.
*/
memset(&mig_stats, 0, sizeof(mig_stats));
+ mig_stats.dirty_sync_count = 1;
+
migration_reset_vfio_bytes_transferred();
s->postcopy_package_loaded = false;
static void migration_iteration_go_next(MigPendingData *pending)
{
/*
- * Do a slow sync will achieve this. TODO: move RAM iteration code
- * into the core layer.
+ * Do a slow sync first before boosting the iteration count.
*/
qemu_savevm_query_pending(pending, true);
+
+ /*
+ * Boost dirty sync count to reflect we finished one iteration.
+ *
+ * NOTE: we need to make sure when this happens (together with the
+ * event sent below) all modules have slow-synced the pending data
+ * above. That means a write mem barrier, but qatomic_add() should be
+ * enough.
+ *
+ * It's because a mgmt could wait on the iteration event to query again
+ * on pending data for policy changes (e.g. downtime adjustments). The
+ * ordering will make sure the query will fetch the latest results from
+ * all the modules.
+ */
+ qatomic_add(&mig_stats.dirty_sync_count, 1);
+
+ if (migrate_events()) {
+ qapi_event_send_migration_pass(mig_stats.dirty_sync_count);
+ }
}
static bool postcopy_should_start(MigrationState *s, MigPendingData *pending)
RAMBlock *block;
int64_t end_time;
- qatomic_add(&mig_stats.dirty_sync_count, 1);
-
if (!rs->time_last_bitmap_sync) {
rs->time_last_bitmap_sync = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
}
rs->num_dirty_pages_period = 0;
rs->bytes_xfer_prev = migration_transferred_bytes();
}
- if (migrate_events()) {
- uint64_t generation = qatomic_read(&mig_stats.dirty_sync_count);
- qapi_event_send_migration_pass(generation);
- }
}
void migration_bitmap_sync_precopy(bool last_stage)