}
static QapiVfioMigrationState
-mig_state_to_qapi_state(enum vfio_device_mig_state state)
+mig_state_to_qapi_state(enum vfio_device_mig_state state, bool prepare)
{
switch (state) {
case VFIO_DEVICE_STATE_STOP:
case VFIO_DEVICE_STATE_PRE_COPY:
return QAPI_VFIO_MIGRATION_STATE_PRE_COPY;
case VFIO_DEVICE_STATE_PRE_COPY_P2P:
- return QAPI_VFIO_MIGRATION_STATE_PRE_COPY_P2P;
+ return prepare ? QAPI_VFIO_MIGRATION_STATE_PRE_COPY_P2P_PREPARE :
+ QAPI_VFIO_MIGRATION_STATE_PRE_COPY_P2P;
default:
g_assert_not_reached();
}
}
-static void vfio_migration_send_event(VFIODevice *vbasedev)
+static void vfio_migration_send_event(VFIODevice *vbasedev,
+ enum vfio_device_mig_state state,
+ bool prepare)
{
- VFIOMigration *migration = vbasedev->migration;
DeviceState *dev = vbasedev->dev;
g_autofree char *qom_path = NULL;
Object *obj;
g_assert(obj);
qom_path = object_get_canonical_path(obj);
- qapi_event_send_vfio_migration(
- dev->id, qom_path, mig_state_to_qapi_state(migration->device_state));
+ qapi_event_send_vfio_migration(dev->id, qom_path,
+ mig_state_to_qapi_state(state, prepare));
}
static void vfio_migration_set_device_state(VFIODevice *vbasedev,
mig_state_to_str(state));
migration->device_state = state;
- vfio_migration_send_event(vbasedev);
+ vfio_migration_send_event(vbasedev, state, false);
}
int vfio_migration_set_state(VFIODevice *vbasedev,
return 0;
}
+ /*
+ * Send a prepare event before initiating the PRE_COPY_P2P transition to
+ * ensure timely event delivery regardless of how long the state transition
+ * takes.
+ */
+ if (new_state == VFIO_DEVICE_STATE_PRE_COPY_P2P) {
+ vfio_migration_send_event(vbasedev, VFIO_DEVICE_STATE_PRE_COPY_P2P,
+ true);
+ }
+
feature->argsz = sizeof(buf);
feature->flags =
VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE;
##
# @QapiVfioMigrationState:
#
-# An enumeration of the VFIO device migration states.
+# An enumeration of the VFIO device migration states. In addition to
+# the regular states, there are prepare states (with 'prepare' suffix)
+# which indicate that the device is just about to transition to the
+# corresponding state. Note that seeing a prepare state for state X
+# doesn't guarantee that the next state will be X, as the state
+# transition can fail and the device may transition to a different
+# state instead.
#
# @stop: The device is stopped.
#
# tracking its internal state and its internal state is available
# for reading.
#
+# @pre-copy-p2p-prepare: The device is just about to move to
+# pre-copy-p2p state. (since 11.0)
+#
# Since: 9.1
##
{ 'enum': 'QapiVfioMigrationState',
'data': [ 'stop', 'running', 'stop-copy', 'resuming', 'running-p2p',
- 'pre-copy', 'pre-copy-p2p' ] }
+ 'pre-copy', 'pre-copy-p2p', 'pre-copy-p2p-prepare' ] }
##
# @VFIO_MIGRATION: