Skip to content

Commit 6de0422

Browse files
Yishai Hadasawilliam
authored andcommitted
vfio/mlx5: Let firmware knows upon leaving PRE_COPY back to RUNNING
Let firmware knows upon leaving PRE_COPY back to RUNNING as of some error in the target/migration cancellation. This will let firmware cleaning its internal resources that were turned on upon PRE_COPY. The flow is based on the device specification in this area. Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Acked-by: Leon Romanovsky <leon@kernel.org> Link: https://lore.kernel.org/r/20240205124828.232701-6-yishaih@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent d8d577b commit 6de0422

File tree

3 files changed

+45
-12
lines changed

3 files changed

+45
-12
lines changed

drivers/vfio/pci/mlx5/cmd.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ int mlx5vf_cmd_query_vhca_migration_state(struct mlx5vf_pci_core_device *mvdev,
108108
ret = wait_for_completion_interruptible(&mvdev->saving_migf->save_comp);
109109
if (ret)
110110
return ret;
111-
if (mvdev->saving_migf->state ==
112-
MLX5_MIGF_STATE_PRE_COPY_ERROR) {
111+
/* Upon cleanup, ignore previous pre_copy error state */
112+
if (mvdev->saving_migf->state == MLX5_MIGF_STATE_PRE_COPY_ERROR &&
113+
!(query_flags & MLX5VF_QUERY_CLEANUP)) {
113114
/*
114115
* In case we had a PRE_COPY error, only query full
115116
* image for final image
@@ -200,7 +201,7 @@ void mlx5vf_cmd_close_migratable(struct mlx5vf_pci_core_device *mvdev)
200201
/* Must be done outside the lock to let it progress */
201202
set_tracker_error(mvdev);
202203
mutex_lock(&mvdev->state_mutex);
203-
mlx5vf_disable_fds(mvdev);
204+
mlx5vf_disable_fds(mvdev, NULL);
204205
_mlx5vf_free_page_tracker_resources(mvdev);
205206
mlx5vf_state_mutex_unlock(mvdev);
206207
}
@@ -639,6 +640,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
639640
u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {};
640641
struct mlx5_vhca_data_buffer *header_buf = NULL;
641642
struct mlx5vf_async_data *async_data;
643+
bool pre_copy_cleanup = false;
642644
int err;
643645

644646
lockdep_assert_held(&mvdev->state_mutex);
@@ -649,6 +651,10 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
649651
if (err)
650652
return err;
651653

654+
if ((migf->state == MLX5_MIGF_STATE_PRE_COPY ||
655+
migf->state == MLX5_MIGF_STATE_PRE_COPY_ERROR) && !track && !inc)
656+
pre_copy_cleanup = true;
657+
652658
if (migf->state == MLX5_MIGF_STATE_PRE_COPY_ERROR)
653659
/*
654660
* In case we had a PRE_COPY error, SAVE is triggered only for
@@ -667,7 +673,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
667673

668674
async_data = &migf->async_data;
669675
async_data->buf = buf;
670-
async_data->stop_copy_chunk = !track;
676+
async_data->stop_copy_chunk = (!track && !pre_copy_cleanup);
671677
async_data->out = kvzalloc(out_size, GFP_KERNEL);
672678
if (!async_data->out) {
673679
err = -ENOMEM;

drivers/vfio/pci/mlx5/cmd.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ struct mlx5vf_pci_core_device {
197197
enum {
198198
MLX5VF_QUERY_INC = (1UL << 0),
199199
MLX5VF_QUERY_FINAL = (1UL << 1),
200+
MLX5VF_QUERY_CLEANUP = (1UL << 2),
200201
};
201202

202203
int mlx5vf_cmd_suspend_vhca(struct mlx5vf_pci_core_device *mvdev, u16 op_mod);
@@ -232,7 +233,8 @@ int mlx5vf_add_migration_pages(struct mlx5_vhca_data_buffer *buf,
232233
struct page *mlx5vf_get_migration_page(struct mlx5_vhca_data_buffer *buf,
233234
unsigned long offset);
234235
void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev);
235-
void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev);
236+
void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev,
237+
enum mlx5_vf_migf_state *last_save_state);
236238
void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work);
237239
void mlx5vf_mig_file_set_save_work(struct mlx5_vf_migration_file *migf,
238240
u8 chunk_num, size_t next_required_umem_size);

drivers/vfio/pci/mlx5/main.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,8 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
11461146
return ERR_PTR(ret);
11471147
}
11481148

1149-
void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev)
1149+
void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev,
1150+
enum mlx5_vf_migf_state *last_save_state)
11501151
{
11511152
if (mvdev->resuming_migf) {
11521153
mlx5vf_disable_fd(mvdev->resuming_migf);
@@ -1157,6 +1158,8 @@ void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev)
11571158
if (mvdev->saving_migf) {
11581159
mlx5_cmd_cleanup_async_ctx(&mvdev->saving_migf->async_ctx);
11591160
cancel_work_sync(&mvdev->saving_migf->async_data.work);
1161+
if (last_save_state)
1162+
*last_save_state = mvdev->saving_migf->state;
11601163
mlx5vf_disable_fd(mvdev->saving_migf);
11611164
wake_up_interruptible(&mvdev->saving_migf->poll_wait);
11621165
mlx5fv_cmd_clean_migf_resources(mvdev->saving_migf);
@@ -1217,12 +1220,34 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev,
12171220
return migf->filp;
12181221
}
12191222

1220-
if ((cur == VFIO_DEVICE_STATE_STOP_COPY && new == VFIO_DEVICE_STATE_STOP) ||
1221-
(cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING) ||
1223+
if (cur == VFIO_DEVICE_STATE_STOP_COPY && new == VFIO_DEVICE_STATE_STOP) {
1224+
mlx5vf_disable_fds(mvdev, NULL);
1225+
return NULL;
1226+
}
1227+
1228+
if ((cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING) ||
12221229
(cur == VFIO_DEVICE_STATE_PRE_COPY_P2P &&
12231230
new == VFIO_DEVICE_STATE_RUNNING_P2P)) {
1224-
mlx5vf_disable_fds(mvdev);
1225-
return NULL;
1231+
struct mlx5_vf_migration_file *migf = mvdev->saving_migf;
1232+
struct mlx5_vhca_data_buffer *buf;
1233+
enum mlx5_vf_migf_state state;
1234+
size_t size;
1235+
1236+
ret = mlx5vf_cmd_query_vhca_migration_state(mvdev, &size, NULL,
1237+
MLX5VF_QUERY_INC | MLX5VF_QUERY_CLEANUP);
1238+
if (ret)
1239+
return ERR_PTR(ret);
1240+
buf = mlx5vf_get_data_buffer(migf, size, DMA_FROM_DEVICE);
1241+
if (IS_ERR(buf))
1242+
return ERR_CAST(buf);
1243+
/* pre_copy cleanup */
1244+
ret = mlx5vf_cmd_save_vhca_state(mvdev, migf, buf, false, false);
1245+
if (ret) {
1246+
mlx5vf_put_data_buffer(buf);
1247+
return ERR_PTR(ret);
1248+
}
1249+
mlx5vf_disable_fds(mvdev, &state);
1250+
return (state != MLX5_MIGF_STATE_ERROR) ? NULL : ERR_PTR(-EIO);
12261251
}
12271252

12281253
if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_RESUMING) {
@@ -1244,7 +1269,7 @@ mlx5vf_pci_step_device_state_locked(struct mlx5vf_pci_core_device *mvdev,
12441269
if (ret)
12451270
return ERR_PTR(ret);
12461271
}
1247-
mlx5vf_disable_fds(mvdev);
1272+
mlx5vf_disable_fds(mvdev, NULL);
12481273
return NULL;
12491274
}
12501275

@@ -1289,7 +1314,7 @@ void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev)
12891314
mvdev->deferred_reset = false;
12901315
spin_unlock(&mvdev->reset_lock);
12911316
mvdev->mig_state = VFIO_DEVICE_STATE_RUNNING;
1292-
mlx5vf_disable_fds(mvdev);
1317+
mlx5vf_disable_fds(mvdev, NULL);
12931318
goto again;
12941319
}
12951320
mutex_unlock(&mvdev->state_mutex);

0 commit comments

Comments
 (0)