Skip to content

Commit d9a871e

Browse files
shamiali2008awilliam
authored andcommitted
hisi_acc_vfio_pci: Introduce support for PRE_COPY state transitions
The saving_migf is open in PRE_COPY state if it is supported and reads initial device match data. hisi_acc_vf_stop_copy() is refactored to make use of common code. Signed-off-by: Shameer Kolothum <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 64ffbbb commit d9a871e

File tree

1 file changed

+71
-3
lines changed

1 file changed

+71
-3
lines changed

drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ static const struct file_operations hisi_acc_vf_save_fops = {
863863
};
864864

865865
static struct hisi_acc_vf_migration_file *
866-
hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
866+
hisi_acc_open_saving_migf(struct hisi_acc_vf_core_device *hisi_acc_vdev)
867867
{
868868
struct hisi_acc_vf_migration_file *migf;
869869
int ret;
@@ -885,7 +885,7 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
885885
mutex_init(&migf->lock);
886886
migf->hisi_acc_vdev = hisi_acc_vdev;
887887

888-
ret = vf_qm_state_save(hisi_acc_vdev, migf);
888+
ret = vf_qm_get_match_data(hisi_acc_vdev, &migf->vf_data);
889889
if (ret) {
890890
fput(migf->filp);
891891
return ERR_PTR(ret);
@@ -894,6 +894,44 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
894894
return migf;
895895
}
896896

897+
static struct hisi_acc_vf_migration_file *
898+
hisi_acc_vf_pre_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
899+
{
900+
struct hisi_acc_vf_migration_file *migf;
901+
902+
migf = hisi_acc_open_saving_migf(hisi_acc_vdev);
903+
if (IS_ERR(migf))
904+
return migf;
905+
906+
migf->total_length = QM_MATCH_SIZE;
907+
return migf;
908+
}
909+
910+
static struct hisi_acc_vf_migration_file *
911+
hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev, bool open)
912+
{
913+
int ret;
914+
struct hisi_acc_vf_migration_file *migf = NULL;
915+
916+
if (open) {
917+
/*
918+
* Userspace didn't use PRECOPY support. Hence saving_migf
919+
* is not opened yet.
920+
*/
921+
migf = hisi_acc_open_saving_migf(hisi_acc_vdev);
922+
if (IS_ERR(migf))
923+
return migf;
924+
} else {
925+
migf = hisi_acc_vdev->saving_migf;
926+
}
927+
928+
ret = vf_qm_state_save(hisi_acc_vdev, migf);
929+
if (ret)
930+
return ERR_PTR(ret);
931+
932+
return open ? migf : NULL;
933+
}
934+
897935
static int hisi_acc_vf_stop_device(struct hisi_acc_vf_core_device *hisi_acc_vdev)
898936
{
899937
struct device *dev = &hisi_acc_vdev->vf_dev->dev;
@@ -921,6 +959,31 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
921959
u32 cur = hisi_acc_vdev->mig_state;
922960
int ret;
923961

962+
if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_PRE_COPY) {
963+
struct hisi_acc_vf_migration_file *migf;
964+
965+
migf = hisi_acc_vf_pre_copy(hisi_acc_vdev);
966+
if (IS_ERR(migf))
967+
return ERR_CAST(migf);
968+
get_file(migf->filp);
969+
hisi_acc_vdev->saving_migf = migf;
970+
return migf->filp;
971+
}
972+
973+
if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_STOP_COPY) {
974+
struct hisi_acc_vf_migration_file *migf;
975+
976+
ret = hisi_acc_vf_stop_device(hisi_acc_vdev);
977+
if (ret)
978+
return ERR_PTR(ret);
979+
980+
migf = hisi_acc_vf_stop_copy(hisi_acc_vdev, false);
981+
if (IS_ERR(migf))
982+
return ERR_CAST(migf);
983+
984+
return NULL;
985+
}
986+
924987
if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_STOP) {
925988
ret = hisi_acc_vf_stop_device(hisi_acc_vdev);
926989
if (ret)
@@ -931,7 +994,7 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
931994
if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_STOP_COPY) {
932995
struct hisi_acc_vf_migration_file *migf;
933996

934-
migf = hisi_acc_vf_stop_copy(hisi_acc_vdev);
997+
migf = hisi_acc_vf_stop_copy(hisi_acc_vdev, true);
935998
if (IS_ERR(migf))
936999
return ERR_CAST(migf);
9371000
get_file(migf->filp);
@@ -963,6 +1026,11 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
9631026
return NULL;
9641027
}
9651028

1029+
if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING) {
1030+
hisi_acc_vf_disable_fds(hisi_acc_vdev);
1031+
return NULL;
1032+
}
1033+
9661034
if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_RUNNING) {
9671035
hisi_acc_vf_start_device(hisi_acc_vdev);
9681036
return NULL;

0 commit comments

Comments
 (0)