在 2022/8/25 16:08, Kangjie Xu 写道:
> From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
>
> PCI devices support vq reset.
>
> Based on this function, the driver can adjust the size of the ring, and
> quickly recycle the buffer in the ring.
>
> The migration of the virtio devices will not happen during a reset
> operation. This is becuase the global iothread lock is held. Migration
> thread also needs the lock. As a result, when migration of virtio
> devices starts, the 'reset' status of VirtIOPCIQueue will always be 0.
> Thus, we do not need to add it in vmstate_virtio_pci_modern_queue_state.
>
> Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> Signed-off-by: Kangjie Xu <kangjie.xu@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
> ---
> hw/virtio/virtio-pci.c | 15 +++++++++++++++
> include/hw/virtio/virtio-pci.h | 5 +++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index a50c5a57d7..79b9e641dd 100644
> --- a/hw/virtio/virtio-pci.c
> +++ b/hw/virtio/virtio-pci.c
> @@ -1251,6 +1251,9 @@ static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
> case VIRTIO_PCI_COMMON_Q_USEDHI:
> val = proxy->vqs[vdev->queue_sel].used[1];
> break;
> + case VIRTIO_PCI_COMMON_Q_RESET:
> + val = proxy->vqs[vdev->queue_sel].reset;
> + break;
> default:
> val = 0;
> }
> @@ -1338,6 +1341,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
> ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |
> proxy->vqs[vdev->queue_sel].used[0]);
> proxy->vqs[vdev->queue_sel].enabled = 1;
> + proxy->vqs[vdev->queue_sel].reset = 0;
> } else {
> virtio_error(vdev, "wrong value for queue_enable %"PRIx64, val);
> }
> @@ -1360,6 +1364,16 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
> case VIRTIO_PCI_COMMON_Q_USEDHI:
> proxy->vqs[vdev->queue_sel].used[1] = val;
> break;
> + case VIRTIO_PCI_COMMON_Q_RESET:
> + if (val == 1) {
> + proxy->vqs[vdev->queue_sel].reset = 1;
> +
> + virtio_queue_reset(vdev, vdev->queue_sel);
> +
> + proxy->vqs[vdev->queue_sel].reset = 0;
> + proxy->vqs[vdev->queue_sel].enabled = 0;
> + }
> + break;
> default:
> break;
> }
> @@ -1954,6 +1968,7 @@ static void virtio_pci_reset(DeviceState *qdev)
>
> for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
> proxy->vqs[i].enabled = 0;
> + proxy->vqs[i].reset = 0;
> proxy->vqs[i].num = 0;
> proxy->vqs[i].desc[0] = proxy->vqs[i].desc[1] = 0;
> proxy->vqs[i].avail[0] = proxy->vqs[i].avail[1] = 0;
> diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
> index 2446dcd9ae..938799e8f6 100644
> --- a/include/hw/virtio/virtio-pci.h
> +++ b/include/hw/virtio/virtio-pci.h
> @@ -117,6 +117,11 @@ typedef struct VirtIOPCIRegion {
> typedef struct VirtIOPCIQueue {
> uint16_t num;
> bool enabled;
> + /*
> + * No need to migrate the reset status, because it is always 0
> + * when the migration starts.
> + */
> + bool reset;
> uint32_t desc[2];
> uint32_t avail[2];
> uint32_t used[2];