In the process of queue reset, vq leaves vdev->vqs, so the original processing logic may miss some vq. So modify the processing method of releasing vq. Release vq by listing vqs. Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> --- drivers/virtio/virtio_pci_common.c | 22 ++++++++++++++++++---- drivers/virtio/virtio_pci_common.h | 2 ++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index fdbde1db5ec5..6b2573ec1ae8 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -260,12 +260,20 @@ static void vp_del_vq(struct virtqueue *vq) void vp_del_vqs(struct virtio_device *vdev) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); - struct virtqueue *vq, *n; - int i; + struct virtio_pci_vq_info *info; + struct virtqueue *vq; + int i, v; + + for (i = 0; i < vp_dev->nvqs; ++i) { + + info = vp_dev->vqs[i]; + if (!info) + continue; + + vq = info->vq; - list_for_each_entry_safe(vq, n, &vdev->vqs, list) { if (vp_dev->per_vq_vectors) { - int v = vp_dev->vqs[vq->index]->msix_vector; + v = info->msix_vector; if (v != VIRTIO_MSI_NO_VECTOR) { int irq = pci_irq_vector(vp_dev->pci_dev, v); @@ -275,6 +283,7 @@ void vp_del_vqs(struct virtio_device *vdev) } } vp_del_vq(vq); + vp_dev->vqs[i] = NULL; } vp_dev->per_vq_vectors = false; @@ -308,6 +317,7 @@ void vp_del_vqs(struct virtio_device *vdev) vp_dev->msix_affinity_masks = NULL; kfree(vp_dev->vqs); vp_dev->vqs = NULL; + vp_dev->nvqs = 0; } static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, @@ -324,6 +334,8 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs, if (!vp_dev->vqs) return -ENOMEM; + vp_dev->nvqs = nvqs; + if (per_vq_vectors) { /* Best option: one for change interrupt, one per vq. */ nvectors = 1; @@ -395,6 +407,8 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs, if (!vp_dev->vqs) return -ENOMEM; + vp_dev->nvqs = nvqs; + err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED, dev_name(&vdev->dev), vp_dev); if (err) diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index 23f6c5c678d5..392d990b7c73 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h @@ -60,6 +60,8 @@ struct virtio_pci_device { /* array of all queues for house-keeping */ struct virtio_pci_vq_info **vqs; + u32 nvqs; + /* MSI-X support */ int msix_enabled; int intx_enabled; -- 2.31.0