In the current design, we stop the device from operating on the vring during per-queue reset by resetting the structure VirtQueue.
But before the reset operation, when recycling some resources, we should stop referencing new vring resources. For example, when recycling virtio-net's asynchronous sending resources, virtio-net should be able to perceive that the current queue is in the per-queue reset state, and stop sending new packets from the tx queue. Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com> --- hw/virtio/virtio.c | 15 +++++++++++++++ include/hw/virtio/virtio.h | 1 + 2 files changed, 16 insertions(+) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index f35178f5fc..c954f2a2b3 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -142,6 +142,8 @@ struct VirtQueue /* Notification enabled? */ bool notification; + bool disabled_by_reset; + uint16_t queue_index; unsigned int inuse; @@ -2079,6 +2081,12 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index) { VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + /* + * Mark this queue is per-queue reset status. The device should release the + * references of the vring, and not refer more new vring item. + */ + vdev->vq[queue_index].disabled_by_reset = true; + if (k->queue_reset) { k->queue_reset(vdev, queue_index); } @@ -2102,11 +2110,18 @@ void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index) } */ + vdev->vq[queue_index].disabled_by_reset = false; + if (k->queue_enable) { k->queue_enable(vdev, queue_index); } } +bool virtio_queue_reset_state(VirtQueue *vq) +{ + return vq->disabled_by_reset; +} + void virtio_reset(void *opaque) { VirtIODevice *vdev = opaque; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 77c6c55929..00e91af7c4 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -319,6 +319,7 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val); void virtio_reset(void *opaque); void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index); void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index); +bool virtio_queue_reset_state(VirtQueue *vq); void virtio_update_irq(VirtIODevice *vdev); int virtio_set_features(VirtIODevice *vdev, uint64_t val); -- 2.32.0.3.g01195cf9f