vfio/mlx5: Refactor PD usage
authorYishai Hadas <yishaih@nvidia.com>
Tue, 6 Dec 2022 08:34:28 +0000 (10:34 +0200)
committerAlex Williamson <alex.williamson@redhat.com>
Tue, 6 Dec 2022 19:36:44 +0000 (12:36 -0700)
This patch refactors PD usage such as its life cycle will be as of the
migration file instead of allocating/destroying it upon each SAVE/LOAD
command.

This is a preparation step towards the PRE_COPY series where multiple
images will be SAVED/LOADED and a single PD can be simply reused.

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
Link: https://lore.kernel.org/r/20221206083438.37807-5-yishaih@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/mlx5/cmd.c
drivers/vfio/pci/mlx5/cmd.h
drivers/vfio/pci/mlx5/main.c

index 55ee803..a97eac4 100644 (file)
@@ -279,7 +279,6 @@ void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work)
 
        mlx5_core_destroy_mkey(mdev, async_data->mkey);
        dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0);
-       mlx5_core_dealloc_pd(mdev, async_data->pdn);
        kvfree(async_data->out);
        complete(&migf->save_comp);
        fput(migf->filp);
@@ -314,7 +313,7 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
        u32 in[MLX5_ST_SZ_DW(save_vhca_state_in)] = {};
        struct mlx5vf_async_data *async_data;
        struct mlx5_core_dev *mdev;
-       u32 pdn, mkey;
+       u32 mkey;
        int err;
 
        lockdep_assert_held(&mvdev->state_mutex);
@@ -326,16 +325,12 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
        if (err)
                return err;
 
-       err = mlx5_core_alloc_pd(mdev, &pdn);
-       if (err)
-               return err;
-
        err = dma_map_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE,
                              0);
        if (err)
                goto err_dma_map;
 
-       err = _create_mkey(mdev, pdn, migf, NULL, &mkey);
+       err = _create_mkey(mdev, migf->pdn, migf, NULL, &mkey);
        if (err)
                goto err_create_mkey;
 
@@ -357,7 +352,6 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
        migf->total_length = 0;
        get_file(migf->filp);
        async_data->mkey = mkey;
-       async_data->pdn = pdn;
        err = mlx5_cmd_exec_cb(&migf->async_ctx, in, sizeof(in),
                               async_data->out,
                               out_size, mlx5vf_save_callback,
@@ -375,7 +369,6 @@ err_out:
 err_create_mkey:
        dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_FROM_DEVICE, 0);
 err_dma_map:
-       mlx5_core_dealloc_pd(mdev, pdn);
        complete(&migf->save_comp);
        return err;
 }
@@ -386,7 +379,7 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev,
        struct mlx5_core_dev *mdev;
        u32 out[MLX5_ST_SZ_DW(load_vhca_state_out)] = {};
        u32 in[MLX5_ST_SZ_DW(load_vhca_state_in)] = {};
-       u32 pdn, mkey;
+       u32 mkey;
        int err;
 
        lockdep_assert_held(&mvdev->state_mutex);
@@ -400,15 +393,11 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev,
        }
 
        mdev = mvdev->mdev;
-       err = mlx5_core_alloc_pd(mdev, &pdn);
-       if (err)
-               goto end;
-
        err = dma_map_sgtable(mdev->device, &migf->table.sgt, DMA_TO_DEVICE, 0);
        if (err)
-               goto err_reg;
+               goto end;
 
-       err = _create_mkey(mdev, pdn, migf, NULL, &mkey);
+       err = _create_mkey(mdev, migf->pdn, migf, NULL, &mkey);
        if (err)
                goto err_mkey;
 
@@ -424,13 +413,41 @@ int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev,
        mlx5_core_destroy_mkey(mdev, mkey);
 err_mkey:
        dma_unmap_sgtable(mdev->device, &migf->table.sgt, DMA_TO_DEVICE, 0);
-err_reg:
-       mlx5_core_dealloc_pd(mdev, pdn);
 end:
        mutex_unlock(&migf->lock);
        return err;
 }
 
+int mlx5vf_cmd_alloc_pd(struct mlx5_vf_migration_file *migf)
+{
+       int err;
+
+       lockdep_assert_held(&migf->mvdev->state_mutex);
+       if (migf->mvdev->mdev_detach)
+               return -ENOTCONN;
+
+       err = mlx5_core_alloc_pd(migf->mvdev->mdev, &migf->pdn);
+       return err;
+}
+
+void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf)
+{
+       lockdep_assert_held(&migf->mvdev->state_mutex);
+       if (migf->mvdev->mdev_detach)
+               return;
+
+       mlx5_core_dealloc_pd(migf->mvdev->mdev, migf->pdn);
+}
+
+void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf)
+{
+       lockdep_assert_held(&migf->mvdev->state_mutex);
+
+       WARN_ON(migf->mvdev->mdev_detach);
+
+       mlx5vf_cmd_dealloc_pd(migf);
+}
+
 static void combine_ranges(struct rb_root_cached *root, u32 cur_nodes,
                           u32 req_nodes)
 {
index 8ffa769..ba760f9 100644 (file)
@@ -16,7 +16,6 @@ struct mlx5vf_async_data {
        struct mlx5_async_work cb_work;
        struct work_struct work;
        int status;
-       u32 pdn;
        u32 mkey;
        void *out;
 };
@@ -27,6 +26,7 @@ struct mlx5_vf_migration_file {
        u8 disabled:1;
        u8 is_err:1;
 
+       u32 pdn;
        struct sg_append_table table;
        size_t total_length;
        size_t allocated_length;
@@ -127,6 +127,9 @@ int mlx5vf_cmd_save_vhca_state(struct mlx5vf_pci_core_device *mvdev,
                               struct mlx5_vf_migration_file *migf);
 int mlx5vf_cmd_load_vhca_state(struct mlx5vf_pci_core_device *mvdev,
                               struct mlx5_vf_migration_file *migf);
+int mlx5vf_cmd_alloc_pd(struct mlx5_vf_migration_file *migf);
+void mlx5vf_cmd_dealloc_pd(struct mlx5_vf_migration_file *migf);
+void mlx5fv_cmd_clean_migf_resources(struct mlx5_vf_migration_file *migf);
 void mlx5vf_state_mutex_unlock(struct mlx5vf_pci_core_device *mvdev);
 void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev);
 void mlx5vf_mig_file_cleanup_cb(struct work_struct *_work);
index 0d71ebb..1916f7c 100644 (file)
@@ -236,12 +236,15 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev)
        migf->filp = anon_inode_getfile("mlx5vf_mig", &mlx5vf_save_fops, migf,
                                        O_RDONLY);
        if (IS_ERR(migf->filp)) {
-               int err = PTR_ERR(migf->filp);
-
-               kfree(migf);
-               return ERR_PTR(err);
+               ret = PTR_ERR(migf->filp);
+               goto end;
        }
 
+       migf->mvdev = mvdev;
+       ret = mlx5vf_cmd_alloc_pd(migf);
+       if (ret)
+               goto out_free;
+
        stream_open(migf->filp->f_inode, migf->filp);
        mutex_init(&migf->lock);
        init_waitqueue_head(&migf->poll_wait);
@@ -257,20 +260,25 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev)
        ret = mlx5vf_cmd_query_vhca_migration_state(mvdev,
                                                    &migf->total_length);
        if (ret)
-               goto out_free;
+               goto out_pd;
 
        ret = mlx5vf_add_migration_pages(
                migf, DIV_ROUND_UP_ULL(migf->total_length, PAGE_SIZE));
        if (ret)
-               goto out_free;
+               goto out_pd;
 
-       migf->mvdev = mvdev;
        ret = mlx5vf_cmd_save_vhca_state(mvdev, migf);
        if (ret)
-               goto out_free;
+               goto out_save;
        return migf;
+out_save:
+       mlx5vf_disable_fd(migf);
+out_pd:
+       mlx5vf_cmd_dealloc_pd(migf);
 out_free:
        fput(migf->filp);
+end:
+       kfree(migf);
        return ERR_PTR(ret);
 }
 
@@ -352,6 +360,7 @@ static struct mlx5_vf_migration_file *
 mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
 {
        struct mlx5_vf_migration_file *migf;
+       int ret;
 
        migf = kzalloc(sizeof(*migf), GFP_KERNEL);
        if (!migf)
@@ -360,20 +369,30 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev)
        migf->filp = anon_inode_getfile("mlx5vf_mig", &mlx5vf_resume_fops, migf,
                                        O_WRONLY);
        if (IS_ERR(migf->filp)) {
-               int err = PTR_ERR(migf->filp);
-
-               kfree(migf);
-               return ERR_PTR(err);
+               ret = PTR_ERR(migf->filp);
+               goto end;
        }
+
+       migf->mvdev = mvdev;
+       ret = mlx5vf_cmd_alloc_pd(migf);
+       if (ret)
+               goto out_free;
+
        stream_open(migf->filp->f_inode, migf->filp);
        mutex_init(&migf->lock);
        return migf;
+out_free:
+       fput(migf->filp);
+end:
+       kfree(migf);
+       return ERR_PTR(ret);
 }
 
 void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev)
 {
        if (mvdev->resuming_migf) {
                mlx5vf_disable_fd(mvdev->resuming_migf);
+               mlx5fv_cmd_clean_migf_resources(mvdev->resuming_migf);
                fput(mvdev->resuming_migf->filp);
                mvdev->resuming_migf = NULL;
        }
@@ -381,6 +400,7 @@ void mlx5vf_disable_fds(struct mlx5vf_pci_core_device *mvdev)
                mlx5_cmd_cleanup_async_ctx(&mvdev->saving_migf->async_ctx);
                cancel_work_sync(&mvdev->saving_migf->async_data.work);
                mlx5vf_disable_fd(mvdev->saving_migf);
+               mlx5fv_cmd_clean_migf_resources(mvdev->saving_migf);
                fput(mvdev->saving_migf->filp);
                mvdev->saving_migf = NULL;
        }