From 0c0435e7210b99a6bf7b8f8205f7af8277b7525b Mon Sep 17 00:00:00 2001 From: Avihai Horon Date: Sun, 31 Dec 2023 12:48:18 +0200 Subject: [PATCH 063/101] vfio/migration: Add helper function to set state or reset device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Eric Auger RH-MergeRequest: 211: IOMMUFD backend backport RH-Jira: RHEL-19302 RHEL-21057 RH-Acked-by: Cédric Le Goater RH-Acked-by: Sebastian Ott RH-Commit: [62/67] 1a63eea289561a05a6a8527c2a9da0289a7836d9 (eauger1/centos-qemu-kvm) 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 Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé (cherry picked from commit c817e5a377a334241eed149e35760aca58bdeb34) Signed-off-by: Eric Auger --- hw/vfio/migration.c | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c index 28d422b39f..70e6b1a709 100644 --- a/hw/vfio/migration.c +++ b/hw/vfio/migration.c @@ -163,6 +163,19 @@ reset_device: 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) { @@ -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); @@ -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() @@ -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() @@ -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); } } -- 2.39.3