From: Avihai Horon <[email protected]> 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 <[email protected]> Signed-off-by: Avihai Horon <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] Signed-off-by: Cédric Le Goater <[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 a15fc74703998da1956a92c4fb8cfe9ff3a68867..dc741e51421eec6d4ad4d9ce0f9c0c2f6199788d 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 3ab6b7248fea34dec3b58e508f97c8be4c962ce4..ebe2eafded50cdc3c1518a2f1e768fdfe6722c5a 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 fe0d2cc06f946b3f0db28d13994fbd0dfd854fbd..c9d143826d38d77048ecf179cbda19a7184989a4 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -176,7 +176,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.54.0
