Skip to content

Commit

Permalink
hisi_acc_vfio_pci: Introduce support for PRE_COPY state transitions
Browse files Browse the repository at this point in the history
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 <shameerali.kolothum.thodi@huawei.com>
Link: https://lore.kernel.org/r/20221123113236.896-3-shameerali.kolothum.thodi@huawei.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
  • Loading branch information
Shameer Kolothum authored and Alex Williamson committed Dec 6, 2022
1 parent 64ffbbb commit d9a871e
Showing 1 changed file with 71 additions and 3 deletions.
74 changes: 71 additions & 3 deletions drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ static const struct file_operations hisi_acc_vf_save_fops = {
};

static struct hisi_acc_vf_migration_file *
hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
hisi_acc_open_saving_migf(struct hisi_acc_vf_core_device *hisi_acc_vdev)
{
struct hisi_acc_vf_migration_file *migf;
int ret;
Expand All @@ -885,7 +885,7 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
mutex_init(&migf->lock);
migf->hisi_acc_vdev = hisi_acc_vdev;

ret = vf_qm_state_save(hisi_acc_vdev, migf);
ret = vf_qm_get_match_data(hisi_acc_vdev, &migf->vf_data);
if (ret) {
fput(migf->filp);
return ERR_PTR(ret);
Expand All @@ -894,6 +894,44 @@ hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
return migf;
}

static struct hisi_acc_vf_migration_file *
hisi_acc_vf_pre_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev)
{
struct hisi_acc_vf_migration_file *migf;

migf = hisi_acc_open_saving_migf(hisi_acc_vdev);
if (IS_ERR(migf))
return migf;

migf->total_length = QM_MATCH_SIZE;
return migf;
}

static struct hisi_acc_vf_migration_file *
hisi_acc_vf_stop_copy(struct hisi_acc_vf_core_device *hisi_acc_vdev, bool open)
{
int ret;
struct hisi_acc_vf_migration_file *migf = NULL;

if (open) {
/*
* Userspace didn't use PRECOPY support. Hence saving_migf
* is not opened yet.
*/
migf = hisi_acc_open_saving_migf(hisi_acc_vdev);
if (IS_ERR(migf))
return migf;
} else {
migf = hisi_acc_vdev->saving_migf;
}

ret = vf_qm_state_save(hisi_acc_vdev, migf);
if (ret)
return ERR_PTR(ret);

return open ? migf : NULL;
}

static int hisi_acc_vf_stop_device(struct hisi_acc_vf_core_device *hisi_acc_vdev)
{
struct device *dev = &hisi_acc_vdev->vf_dev->dev;
Expand Down Expand Up @@ -921,6 +959,31 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
u32 cur = hisi_acc_vdev->mig_state;
int ret;

if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_PRE_COPY) {
struct hisi_acc_vf_migration_file *migf;

migf = hisi_acc_vf_pre_copy(hisi_acc_vdev);
if (IS_ERR(migf))
return ERR_CAST(migf);
get_file(migf->filp);
hisi_acc_vdev->saving_migf = migf;
return migf->filp;
}

if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_STOP_COPY) {
struct hisi_acc_vf_migration_file *migf;

ret = hisi_acc_vf_stop_device(hisi_acc_vdev);
if (ret)
return ERR_PTR(ret);

migf = hisi_acc_vf_stop_copy(hisi_acc_vdev, false);
if (IS_ERR(migf))
return ERR_CAST(migf);

return NULL;
}

if (cur == VFIO_DEVICE_STATE_RUNNING && new == VFIO_DEVICE_STATE_STOP) {
ret = hisi_acc_vf_stop_device(hisi_acc_vdev);
if (ret)
Expand All @@ -931,7 +994,7 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_STOP_COPY) {
struct hisi_acc_vf_migration_file *migf;

migf = hisi_acc_vf_stop_copy(hisi_acc_vdev);
migf = hisi_acc_vf_stop_copy(hisi_acc_vdev, true);
if (IS_ERR(migf))
return ERR_CAST(migf);
get_file(migf->filp);
Expand Down Expand Up @@ -963,6 +1026,11 @@ hisi_acc_vf_set_device_state(struct hisi_acc_vf_core_device *hisi_acc_vdev,
return NULL;
}

if (cur == VFIO_DEVICE_STATE_PRE_COPY && new == VFIO_DEVICE_STATE_RUNNING) {
hisi_acc_vf_disable_fds(hisi_acc_vdev);
return NULL;
}

if (cur == VFIO_DEVICE_STATE_STOP && new == VFIO_DEVICE_STATE_RUNNING) {
hisi_acc_vf_start_device(hisi_acc_vdev);
return NULL;
Expand Down

0 comments on commit d9a871e

Please sign in to comment.