Add support for the new switchover-ack mechanism. This includes
requesting a switchover ACK on the first save_query_pending call (with
exact=false) if VFIO precopy is supported.
This achieves the same functionality of legacy switchover-ack but with
the new switchover-ack mechanism.
Keep legacy switchover-ack functionality for backward compatibility.
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Avihai Horon <avihaih@nvidia.com>
---
hw/vfio/vfio-migration-internal.h | 1 +
hw/vfio/migration.c | 13 ++++++++++++-
hw/vfio/trace-events | 2 +-
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/hw/vfio/vfio-migration-internal.h b/hw/vfio/vfio-migration-internal.h
index a15fc74703..dc741e5142 100644
--- a/hw/vfio/vfio-migration-internal.h
+++ b/hw/vfio/vfio-migration-internal.h
@@ -58,6 +58,7 @@ typedef struct VFIOMigration {
bool multifd_transfer;
VFIOMultifd *multifd;
bool initial_data_sent;
+ bool request_switchover_ack;
bool event_save_iterate_started;
bool event_precopy_empty_hit;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 3ab6b7248f..ebe2eafded 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -582,6 +582,9 @@ static int vfio_save_setup(QEMUFile *f, void *opaque, Error **errp)
}
vfio_query_precopy_size(migration);
+ if (migrate_switchover_ack() && !migrate_switchover_ack_legacy()) {
+ migration->request_switchover_ack = true;
+ }
break;
case VFIO_DEVICE_STATE_STOP:
@@ -634,6 +637,7 @@ static void vfio_save_cleanup(void *opaque)
migration->precopy_init_size = 0;
migration->precopy_dirty_size = 0;
migration->initial_data_sent = false;
+ migration->request_switchover_ack = false;
vfio_migration_cleanup(vbasedev);
trace_vfio_save_cleanup(vbasedev->name);
}
@@ -655,6 +659,7 @@ static void vfio_state_pending(void *opaque, MigPendingData *pending,
VFIODevice *vbasedev = opaque;
VFIOMigration *migration = vbasedev->migration;
uint64_t precopy_size, stopcopy_size;
+ bool request_switchover_ack = false;
/*
* The final pending query runs during switchover downtime. VFIO does not
@@ -676,10 +681,16 @@ static void vfio_state_pending(void *opaque, MigPendingData *pending,
pending->precopy_bytes += precopy_size;
pending->stopcopy_bytes += stopcopy_size;
+ if (migration->request_switchover_ack) {
+ pending->switchover_ack_pending++;
+ request_switchover_ack = true;
+ migration->request_switchover_ack = false;
+ }
trace_vfio_state_pending(vbasedev->name, migration->stopcopy_size,
migration->precopy_init_size,
- migration->precopy_dirty_size, exact, final);
+ migration->precopy_dirty_size,
+ request_switchover_ack, exact, final);
}
static bool vfio_is_active_iterate(void *opaque)
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 411a306635..53f0ba357b 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -175,7 +175,7 @@ vfio_save_device_config_state(const char *name) " (%s)"
vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy_dirty_size) " (%s) precopy initial size %"PRIu64" precopy dirty size %"PRIu64
vfio_save_iterate_start(const char *name) " (%s)"
vfio_save_setup(const char *name, uint64_t data_buffer_size) " (%s) data buffer size %"PRIu64
-vfio_state_pending(const char *name, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size, bool exact, bool final) " (%s) stopcopy size %"PRIu64", precopy initial size %"PRIu64", precopy dirty size %"PRIu64", exact %d, final %d"
+vfio_state_pending(const char *name, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size, bool request_switchover_ack, bool exact, bool final) " (%s) stopcopy size %"PRIu64", precopy initial size %"PRIu64", precopy dirty size %"PRIu64", request switchover ack %d, exact %d, final %d"
vfio_send_init_data_flag(const char *name) " (%s)"
vfio_vmstate_change(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s"
vfio_vmstate_change_prepare(const char *name, int running, const char *reason, const char *dev_state) " (%s) running %d reason %s device state %s"
--
2.40.1