Signed-off-by: Wei Xu <w...@redhat.com> --- hw/net/virtio-net.c | 22 ++++++++++++++++++++++ include/hw/virtio/virtio-net.h | 1 + 2 files changed, 23 insertions(+)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index a877614..4e9458e 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1603,6 +1603,26 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f, return 0; } + +static void virtio_net_rsc_cleanup(VirtIONet *n) +{ + NetRscChain *chain, *rn_chain; + NetRscSeg *seg, *rn_seg; + + QTAILQ_FOREACH_SAFE(chain, &n->rsc_chains, next, rn_chain) { + QTAILQ_FOREACH_SAFE(seg, &chain->buffers, next, rn_seg) { + QTAILQ_REMOVE(&chain->buffers, seg, next); + g_free(seg->buf); + g_free(seg); + + timer_del(chain->drain_timer); + timer_free(chain->drain_timer); + QTAILQ_REMOVE(&n->rsc_chains, chain, next); + g_free(chain); + } + } +} + static NetClientInfo net_virtio_info = { .type = NET_CLIENT_OPTIONS_KIND_NIC, .size = sizeof(NICState), @@ -1732,6 +1752,7 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp) nc = qemu_get_queue(n->nic); nc->rxfilter_notify_enabled = 1; + QTAILQ_INIT(&n->rsc_chains); n->qdev = dev; register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION, virtio_net_save, virtio_net_load, n); @@ -1766,6 +1787,7 @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp) g_free(n->vqs); qemu_del_nic(n->nic); virtio_cleanup(vdev); + virtio_net_rsc_cleanup(n); } static void virtio_net_instance_init(Object *obj) diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index f3cc25f..6ce8b93 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -59,6 +59,7 @@ typedef struct VirtIONet { VirtIONetQueue *vqs; VirtQueue *ctrl_vq; NICState *nic; + QTAILQ_HEAD(, NetRscChain) rsc_chains; uint32_t tx_timeout; int32_t tx_burst; uint32_t has_vnet_hdr; -- 2.4.0