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 <xuanzhuo@xxxxxxxxxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization