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. Signed-off-by: Avihai Horon <[email protected]> --- 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 02ef216712..2296d0d44b 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; if (final) { return; @@ -675,10 +680,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); + migration->precopy_dirty_size, + request_switchover_ack, exact); } static bool vfio_is_active_iterate(void *opaque) diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events index e99ee2ee8a..50722eb717 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -176,7 +176,7 @@ vfio_save_iterate(const char *name, uint64_t precopy_init_size, uint64_t precopy 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_send_init_data_flag(const char *name) " (%s)" -vfio_state_pending(const char *name, uint64_t stopcopy_size, uint64_t precopy_init_size, uint64_t precopy_dirty_size, bool exact) " (%s) stopcopy size %"PRIu64" precopy initial size %"PRIu64" precopy dirty size %"PRIu64 " exact %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) " (%s) stopcopy size %"PRIu64", precopy initial size %"PRIu64", precopy dirty size %"PRIu64 ", request switchover ack %d, exact %d" 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
