Skip to content

Commit

Permalink
virtio_vdpa: fix rollback when vdpa probe error
Browse files Browse the repository at this point in the history
Signed-off-by: yuanminghao <yuanmh12@chinatelecom.cn>
  • Loading branch information
yuanminghao authored and kailiangz1 committed Jun 20, 2023
1 parent a3238a0 commit f5ae93b
Showing 1 changed file with 80 additions and 69 deletions.
149 changes: 80 additions & 69 deletions drivers/vdpa/virtio/virtio_vdpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -1383,98 +1383,109 @@ virtio_vdpa_get_vfid(const char *pf_name, const char *vf_name, int *vfid)
}

static int
virtio_vdpa_dev_remove(struct rte_pci_device *pci_dev)
virtio_vdpa_dev_do_remove(struct rte_pci_device *pci_dev, struct virtio_vdpa_priv *priv)
{
struct virtio_vdpa_priv *priv = NULL;
bool found = false, ret;
bool ret;

pthread_mutex_lock(&priv_list_lock);
TAILQ_FOREACH(priv, &virtio_priv_list, next) {
if (priv->pdev == pci_dev) {
found = true;
TAILQ_REMOVE(&virtio_priv_list, priv, next);
break;
}
if (!priv)
return 0;

if (priv->configured)
virtio_vdpa_dev_close(priv->vid);

if (priv->dev_work_flag == VIRTIO_VDPA_DEV_CLOSE_WORK_START) {
DRV_LOG(ERR, "%s is waiting dev close work finish lcore:%d", pci_dev->name, priv->lcore_id);
rte_eal_wait_lcore(priv->lcore_id);
}
pthread_mutex_unlock(&priv_list_lock);
if (found) {
if (priv->configured)
virtio_vdpa_dev_close(priv->vid);

if (priv->dev_work_flag == VIRTIO_VDPA_DEV_CLOSE_WORK_START) {
DRV_LOG(ERR, "%s is waiting dev close work finish lcore:%d", pci_dev->name, priv->lcore_id);
rte_eal_wait_lcore(priv->lcore_id);
}
if (priv->dev_work_flag == VIRTIO_VDPA_DEV_CLOSE_WORK_ERR) {
DRV_LOG(ERR, "%s is dev close work had err", pci_dev->name);
}

if (priv->dev_work_flag == VIRTIO_VDPA_DEV_CLOSE_WORK_ERR) {
DRV_LOG(ERR, "%s is dev close work had err", pci_dev->name);
if (priv->dev_ops->unreg_dev_intr) {
ret = virtio_pci_dev_interrupt_disable(priv->vpdev, 0);
if (ret) {
DRV_LOG(ERR, "%s error disabling virtio dev interrupts: %d (%s)",
priv->vdev->device->name,
ret, strerror(errno));
}

if (priv->dev_ops->unreg_dev_intr) {
ret = virtio_pci_dev_interrupt_disable(priv->vpdev, 0);
if (ret) {
DRV_LOG(ERR, "%s error disabling virtio dev interrupts: %d (%s)",
priv->vdev->device->name,
ret, strerror(errno));
}

ret = priv->dev_ops->unreg_dev_intr(priv);
if (ret) {
DRV_LOG(ERR, "%s unregister dev interrupt fail ret:%d", pci_dev->name, ret);
}
ret = priv->dev_ops->unreg_dev_intr(priv);
if (ret) {
DRV_LOG(ERR, "%s unregister dev interrupt fail ret:%d", pci_dev->name, ret);
}
}

if (priv->lm_status == VIRTIO_S_FREEZED) {
ret = virtio_vdpa_cmd_set_status(priv->pf_priv, priv->vf_id, VIRTIO_S_QUIESCED);
if (ret) {
DRV_LOG(ERR, "%s vfid %d failed unfreeze ret:%d", pci_dev->name, priv->vf_id, ret);
}
priv->lm_status = VIRTIO_S_QUIESCED;
if (priv->lm_status == VIRTIO_S_FREEZED) {
ret = virtio_vdpa_cmd_set_status(priv->pf_priv, priv->vf_id, VIRTIO_S_QUIESCED);
if (ret) {
DRV_LOG(ERR, "%s vfid %d failed unfreeze ret:%d", pci_dev->name, priv->vf_id, ret);
}
priv->lm_status = VIRTIO_S_QUIESCED;
}

if (priv->lm_status == VIRTIO_S_QUIESCED) {
ret = virtio_vdpa_cmd_set_status(priv->pf_priv, priv->vf_id, VIRTIO_S_RUNNING);
if (ret) {
DRV_LOG(ERR, "%s vfid %d failed unquiesced ret:%d", pci_dev->name, priv->vf_id, ret);
}
priv->lm_status = VIRTIO_S_RUNNING;
if (priv->lm_status == VIRTIO_S_QUIESCED) {
ret = virtio_vdpa_cmd_set_status(priv->pf_priv, priv->vf_id, VIRTIO_S_RUNNING);
if (ret) {
DRV_LOG(ERR, "%s vfid %d failed unquiesced ret:%d", pci_dev->name, priv->vf_id, ret);
}
priv->lm_status = VIRTIO_S_RUNNING;
}

if (priv->vdev)
rte_vdpa_unregister_device(priv->vdev);
if (priv->vdev)
rte_vdpa_unregister_device(priv->vdev);

if (priv->vpdev) {
ret = virtio_pci_dev_interrupts_free(priv->vpdev);
if (ret) {
DRV_LOG(ERR, "Error free virtio dev interrupts: %s",
strerror(errno));
}
if (priv->vpdev) {
ret = virtio_pci_dev_interrupts_free(priv->vpdev);
if (ret) {
DRV_LOG(ERR, "Error free virtio dev interrupts: %s",
strerror(errno));
}
}

virtio_vdpa_queues_free(priv);
virtio_vdpa_queues_free(priv);

if (priv->vpdev) {
virtio_pci_dev_reset(priv->vpdev, VIRTIO_VDPA_REMOVE_RESET_TIME_OUT);
virtio_pci_dev_free(priv->vpdev);
}
if (priv->vpdev) {
virtio_pci_dev_reset(priv->vpdev, VIRTIO_VDPA_REMOVE_RESET_TIME_OUT);
virtio_pci_dev_free(priv->vpdev);
}

if (priv->vfio_container_fd >= 0)
rte_vfio_container_destroy(priv->vfio_container_fd);
if (priv->vfio_container_fd >= 0)
rte_vfio_container_destroy(priv->vfio_container_fd);

if (priv->state_mz)
rte_memzone_free(priv->state_mz);
if (priv->state_mz)
rte_memzone_free(priv->state_mz);

if (priv->state_mz_remote)
rte_memzone_free(priv->state_mz_remote);
if (priv->vdpa_dp_map)
rte_memzone_free(priv->vdpa_dp_map);
rte_free(priv);
}
if (priv->state_mz_remote)
rte_memzone_free(priv->state_mz_remote);
if (priv->vdpa_dp_map)
rte_memzone_free(priv->vdpa_dp_map);
rte_free(priv);

return found ? 0 : -ENODEV;
return 0;
}

#define VIRTIO_VDPA_GET_GROUPE_RETRIES 120
static int
virtio_vdpa_dev_remove(struct rte_pci_device *pci_dev)
{
struct virtio_vdpa_priv *priv = NULL;
bool found = false;

pthread_mutex_lock(&priv_list_lock);
TAILQ_FOREACH(priv, &virtio_priv_list, next) {
if (priv->pdev == pci_dev) {
found = true;
TAILQ_REMOVE(&virtio_priv_list, priv, next);
break;
}
}
pthread_mutex_unlock(&priv_list_lock);
if (!found)
return -ENODEV;
return virtio_vdpa_dev_do_remove(pci_dev, priv);
}

static int
virtio_vdpa_dev_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
Expand Down Expand Up @@ -1714,7 +1725,7 @@ virtio_vdpa_dev_probe(struct rte_pci_driver *pci_drv __rte_unused,
return 0;

error:
virtio_vdpa_dev_remove(pci_dev);
virtio_vdpa_dev_do_remove(pci_dev, priv);
return -rte_errno;
}

Expand Down

0 comments on commit f5ae93b

Please sign in to comment.