Re: [PATCH vfio 01/13] vfio: Add an option to get migration data size

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2022/11/7 1:46, Yishai Hadas Wrote:
> Add an option to get migration data size by introducing a new migration
> feature named VFIO_DEVICE_FEATURE_MIG_DATA_SIZE.
> 
> Upon VFIO_DEVICE_FEATURE_GET the estimated data length that will be
> required to complete STOP_COPY is returned.
> 
> This option may better enable user space to consider before moving to
> STOP_COPY whether it can meet the downtime SLA based on the returned
> data.
> 
> The patch also includes the implementation for mlx5 and hisi for this
> new option to make it feature complete for the existing drivers in this
> area.
> 
> Signed-off-by: Yishai Hadas <yishaih@xxxxxxxxxx>
> ---
>  .../vfio/pci/hisilicon/hisi_acc_vfio_pci.c    |  9 ++++++
>  drivers/vfio/pci/mlx5/main.c                  | 18 +++++++++++
>  drivers/vfio/pci/vfio_pci_core.c              |  3 +-
>  drivers/vfio/vfio_main.c                      | 32 +++++++++++++++++++
>  include/linux/vfio.h                          |  5 +++
>  include/uapi/linux/vfio.h                     | 13 ++++++++
>  6 files changed, 79 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> index 39eeca18a0f7..0c0c0c7f0521 100644
> --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
> @@ -957,6 +957,14 @@ hisi_acc_vfio_pci_set_device_state(struct vfio_device *vdev,
>  	return res;
>  }
>  
> +static int
> +hisi_acc_vfio_pci_get_data_size(struct vfio_device *vdev,
> +				unsigned long *stop_copy_length)
> +{
> +	*stop_copy_length = sizeof(struct acc_vf_data);
> +	return 0;
> +}
> +
>  static int
>  hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev,
>  				   enum vfio_device_mig_state *curr_state)
> @@ -1213,6 +1221,7 @@ static void hisi_acc_vfio_pci_close_device(struct vfio_device *core_vdev)
>  static const struct vfio_migration_ops hisi_acc_vfio_pci_migrn_state_ops = {
>  	.migration_set_state = hisi_acc_vfio_pci_set_device_state,
>  	.migration_get_state = hisi_acc_vfio_pci_get_device_state,
> +	.migration_get_data_size = hisi_acc_vfio_pci_get_data_size,
>  };
>  

Reviewed-by: Longfang Liu <liulongfang@xxxxxxxxxx>

Thanks.

>  static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
> diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c
> index fd6ccb8454a2..4c7a39ffd247 100644
> --- a/drivers/vfio/pci/mlx5/main.c
> +++ b/drivers/vfio/pci/mlx5/main.c
> @@ -512,6 +512,23 @@ mlx5vf_pci_set_device_state(struct vfio_device *vdev,
>  	return res;
>  }
>  
> +static int mlx5vf_pci_get_data_size(struct vfio_device *vdev,
> +				    unsigned long *stop_copy_length)
> +{
> +	struct mlx5vf_pci_core_device *mvdev = container_of(
> +		vdev, struct mlx5vf_pci_core_device, core_device.vdev);
> +	size_t state_size;
> +	int ret;
> +
> +	mutex_lock(&mvdev->state_mutex);
> +	ret = mlx5vf_cmd_query_vhca_migration_state(mvdev,
> +						    &state_size);
> +	if (!ret)
> +		*stop_copy_length = state_size;
> +	mlx5vf_state_mutex_unlock(mvdev);
> +	return ret;
> +}
> +
>  static int mlx5vf_pci_get_device_state(struct vfio_device *vdev,
>  				       enum vfio_device_mig_state *curr_state)
>  {
> @@ -577,6 +594,7 @@ static void mlx5vf_pci_close_device(struct vfio_device *core_vdev)
>  static const struct vfio_migration_ops mlx5vf_pci_mig_ops = {
>  	.migration_set_state = mlx5vf_pci_set_device_state,
>  	.migration_get_state = mlx5vf_pci_get_device_state,
> +	.migration_get_data_size = mlx5vf_pci_get_data_size,
>  };
>  
>  static const struct vfio_log_ops mlx5vf_pci_log_ops = {
> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
> index badc9d828cac..4d97ca66ba6c 100644
> --- a/drivers/vfio/pci/vfio_pci_core.c
> +++ b/drivers/vfio/pci/vfio_pci_core.c
> @@ -2128,7 +2128,8 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
>  
>  	if (vdev->vdev.mig_ops) {
>  		if (!(vdev->vdev.mig_ops->migration_get_state &&
> -		      vdev->vdev.mig_ops->migration_set_state) ||
> +		      vdev->vdev.mig_ops->migration_set_state &&
> +		      vdev->vdev.mig_ops->migration_get_data_size) ||
>  		    !(vdev->vdev.migration_flags & VFIO_MIGRATION_STOP_COPY))
>  			return -EINVAL;
>  	}
> diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
> index 2d168793d4e1..b118e7b1bc59 100644
> --- a/drivers/vfio/vfio_main.c
> +++ b/drivers/vfio/vfio_main.c
> @@ -1256,6 +1256,34 @@ vfio_ioctl_device_feature_mig_device_state(struct vfio_device *device,
>  	return 0;
>  }
>  
> +static int
> +vfio_ioctl_device_feature_migration_data_size(struct vfio_device *device,
> +					      u32 flags, void __user *arg,
> +					      size_t argsz)
> +{
> +	struct vfio_device_feature_mig_data_size data_size = {};
> +	unsigned long stop_copy_length;
> +	int ret;
> +
> +	if (!device->mig_ops)
> +		return -ENOTTY;
> +
> +	ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_GET,
> +				 sizeof(data_size));
> +	if (ret != 1)
> +		return ret;
> +
> +	ret = device->mig_ops->migration_get_data_size(device, &stop_copy_length);
> +	if (ret)
> +		return ret;
> +
> +	data_size.stop_copy_length = stop_copy_length;
> +	if (copy_to_user(arg, &data_size, sizeof(data_size)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
>  static int vfio_ioctl_device_feature_migration(struct vfio_device *device,
>  					       u32 flags, void __user *arg,
>  					       size_t argsz)
> @@ -1483,6 +1511,10 @@ static int vfio_ioctl_device_feature(struct vfio_device *device,
>  		return vfio_ioctl_device_feature_logging_report(
>  			device, feature.flags, arg->data,
>  			feature.argsz - minsz);
> +	case VFIO_DEVICE_FEATURE_MIG_DATA_SIZE:
> +		return vfio_ioctl_device_feature_migration_data_size(
> +			device, feature.flags, arg->data,
> +			feature.argsz - minsz);
>  	default:
>  		if (unlikely(!device->ops->device_feature))
>  			return -EINVAL;
> diff --git a/include/linux/vfio.h b/include/linux/vfio.h
> index e7cebeb875dd..5509451ae709 100644
> --- a/include/linux/vfio.h
> +++ b/include/linux/vfio.h
> @@ -107,6 +107,9 @@ struct vfio_device_ops {
>   * @migration_get_state: Optional callback to get the migration state for
>   *         devices that support migration. It's mandatory for
>   *         VFIO_DEVICE_FEATURE_MIGRATION migration support.
> + * @migration_get_data_size: Optional callback to get the estimated data
> + *          length that will be required to complete stop copy. It's mandatory for
> + *          VFIO_DEVICE_FEATURE_MIGRATION migration support.
>   */
>  struct vfio_migration_ops {
>  	struct file *(*migration_set_state)(
> @@ -114,6 +117,8 @@ struct vfio_migration_ops {
>  		enum vfio_device_mig_state new_state);
>  	int (*migration_get_state)(struct vfio_device *device,
>  				   enum vfio_device_mig_state *curr_state);
> +	int (*migration_get_data_size)(struct vfio_device *device,
> +				       unsigned long *stop_copy_length);
>  };
>  
>  /**
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index d7d8e0922376..3e45dbaf190e 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -1128,6 +1128,19 @@ struct vfio_device_feature_dma_logging_report {
>  
>  #define VFIO_DEVICE_FEATURE_DMA_LOGGING_REPORT 8
>  
> +/*
> + * Upon VFIO_DEVICE_FEATURE_GET read back the estimated data length that will
> + * be required to complete stop copy.
> + *
> + * Note: Can be called on each device state.
> + */
> +
> +struct vfio_device_feature_mig_data_size {
> +	__aligned_u64 stop_copy_length;
> +};
> +
> +#define VFIO_DEVICE_FEATURE_MIG_DATA_SIZE 9
> +
>  /* -------- API for Type1 VFIO IOMMU -------- */
>  
>  /**
> 



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux