Skip to content

Commit

Permalink
vfio/migration: Add helper function to set state or reset device
Browse files Browse the repository at this point in the history
There are several places where failure in setting the device state leads
to a device reset, which is done by setting ERROR as the recover state.

Add a helper function that sets the device state and resets the device
in case of failure. This will make the code cleaner and remove duplicate
comments.

Signed-off-by: Avihai Horon <avihaih@nvidia.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
  • Loading branch information
avihai1122 authored and legoater committed Jan 5, 2024
1 parent 9f734a1 commit c817e5a
Showing 1 changed file with 17 additions and 24 deletions.
41 changes: 17 additions & 24 deletions hw/vfio/migration.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,19 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
return ret;
}

/*
* Some device state transitions require resetting the device if they fail.
* This function sets the device in new_state and resets the device if that
* fails. Reset is done by using ERROR as the recover state.
*/
static int
vfio_migration_set_state_or_reset(VFIODevice *vbasedev,
enum vfio_device_mig_state new_state)
{
return vfio_migration_set_state(vbasedev, new_state,
VFIO_DEVICE_STATE_ERROR);
}

static int vfio_load_buffer(QEMUFile *f, VFIODevice *vbasedev,
uint64_t data_size)
{
Expand Down Expand Up @@ -422,12 +435,7 @@ static void vfio_save_cleanup(void *opaque)
* after migration has completed, so it won't increase downtime.
*/
if (migration->device_state == VFIO_DEVICE_STATE_STOP_COPY) {
/*
* If setting the device in STOP state fails, the device should be
* reset. To do so, use ERROR state as a recover state.
*/
vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_STOP,
VFIO_DEVICE_STATE_ERROR);
vfio_migration_set_state_or_reset(vbasedev, VFIO_DEVICE_STATE_STOP);
}

g_free(migration->data_buffer);
Expand Down Expand Up @@ -699,12 +707,7 @@ static void vfio_vmstate_change_prepare(void *opaque, bool running,
VFIO_DEVICE_STATE_PRE_COPY_P2P :
VFIO_DEVICE_STATE_RUNNING_P2P;

/*
* If setting the device in new_state fails, the device should be reset.
* To do so, use ERROR state as a recover state.
*/
ret = vfio_migration_set_state(vbasedev, new_state,
VFIO_DEVICE_STATE_ERROR);
ret = vfio_migration_set_state_or_reset(vbasedev, new_state);
if (ret) {
/*
* Migration should be aborted in this case, but vm_state_notify()
Expand Down Expand Up @@ -736,12 +739,7 @@ static void vfio_vmstate_change(void *opaque, bool running, RunState state)
VFIO_DEVICE_STATE_STOP;
}

/*
* If setting the device in new_state fails, the device should be reset.
* To do so, use ERROR state as a recover state.
*/
ret = vfio_migration_set_state(vbasedev, new_state,
VFIO_DEVICE_STATE_ERROR);
ret = vfio_migration_set_state_or_reset(vbasedev, new_state);
if (ret) {
/*
* Migration should be aborted in this case, but vm_state_notify()
Expand Down Expand Up @@ -770,12 +768,7 @@ static void vfio_migration_state_notifier(Notifier *notifier, void *data)
case MIGRATION_STATUS_CANCELLING:
case MIGRATION_STATUS_CANCELLED:
case MIGRATION_STATUS_FAILED:
/*
* If setting the device in RUNNING state fails, the device should
* be reset. To do so, use ERROR state as a recover state.
*/
vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_RUNNING,
VFIO_DEVICE_STATE_ERROR);
vfio_migration_set_state_or_reset(vbasedev, VFIO_DEVICE_STATE_RUNNING);
}
}

Expand Down

0 comments on commit c817e5a

Please sign in to comment.