In vp_modern_enable_vq_after_reset, we will do some checks to ensure
that the vq is ready to re-enable. If that fails, the vq is good.

If the vq_active_vp() fails, that means the vq is broken.
The driver can not use that vq, this commit sets the vq to broken.

Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com>
---
 drivers/virtio/virtio_pci_modern.c |  6 +++---
 drivers/virtio/virtio_ring.c       | 11 ++++++++---
 include/linux/virtio_config.h      |  2 ++
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/virtio/virtio_pci_modern.c 
b/drivers/virtio/virtio_pci_modern.c
index ee6a386d250b..56a4075ca5fb 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -286,16 +286,16 @@ static int vp_modern_enable_vq_after_reset(struct 
virtqueue *vq)
        int err;
 
        if (!vq->reset)
-               return -EBUSY;
+               return -EINVAL;
 
        index = vq->index;
        info = vp_dev->vqs[index];
 
        if (vp_modern_get_queue_reset(mdev, index))
-               return -EBUSY;
+               return -EINVAL;
 
        if (vp_modern_get_queue_enable(mdev, index))
-               return -EBUSY;
+               return -EINVAL;
 
        err = vp_active_vq(vq, info->msix_vector);
        if (err)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index af310418e66e..91e63c57c112 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -2183,11 +2183,16 @@ static int virtqueue_enable_after_reset(struct 
virtqueue *_vq)
 {
        struct vring_virtqueue *vq = to_vvq(_vq);
        struct virtio_device *vdev = vq->vq.vdev;
+       int err;
+
+       err = vdev->config->enable_vq_after_reset(_vq);
+       if (err == -EINVAL || !err)
+               return err;
 
-       if (vdev->config->enable_vq_after_reset(_vq))
-               return -EBUSY;
+       dev_warn(&vdev->dev, "Fail to re-enable the vq.%u error:%d\n", 
_vq->index, err);
+       __virtqueue_unbreak(_vq);
 
-       return 0;
+       return err;
 }
 
 /*
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 2b3438de2c4d..f96bebf9b632 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -91,6 +91,8 @@ typedef void vq_callback_t(struct virtqueue *);
  * @enable_vq_after_reset: enable a reset queue
  *     vq: the virtqueue
  *     Returns 0 on success or error status
+ *     -EINVAL: the vq is not in the reset status or is not ready to enable.
+ *     Other error: enabling vq fails. The vq is in broken status.
  *     If disable_vq_and_reset is set, then enable_vq_after_reset must also be
  *     set.
  */
-- 
2.32.0.3.g01195cf9f

_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Reply via email to