virtio: free MemoryRegionCache when initialization fails

This commit is contained in:
Paolo Bonzini 2018-05-15 15:25:31 +02:00
parent e40077fd2c
commit 45641dba38

View File

@ -123,11 +123,22 @@ static void virtio_free_region_cache(VRingMemoryRegionCaches *caches)
g_free(caches);
}
static void virtio_virtqueue_reset_region_cache(struct VirtQueue *vq)
{
VRingMemoryRegionCaches *caches;
caches = atomic_read(&vq->vring.caches);
atomic_rcu_set(&vq->vring.caches, NULL);
if (caches) {
call_rcu(caches, virtio_free_region_cache, rcu);
}
}
static void virtio_init_region_cache(VirtIODevice *vdev, int n)
{
VirtQueue *vq = &vdev->vq[n];
VRingMemoryRegionCaches *old = vq->vring.caches;
VRingMemoryRegionCaches *new;
VRingMemoryRegionCaches *new = NULL;
hwaddr addr, size;
int event_size;
int64_t len;
@ -136,7 +147,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n)
addr = vq->vring.desc;
if (!addr) {
return;
goto out_no_cache;
}
new = g_new0(VRingMemoryRegionCaches, 1);
size = virtio_queue_get_desc_size(vdev, n);
@ -170,11 +181,14 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n)
return;
err_avail:
address_space_cache_destroy(&new->used);
address_space_cache_destroy(&new->avail);
err_used:
address_space_cache_destroy(&new->desc);
address_space_cache_destroy(&new->used);
err_desc:
address_space_cache_destroy(&new->desc);
out_no_cache:
g_free(new);
virtio_virtqueue_reset_region_cache(vq);
}
/* virt queue functions */
@ -1168,17 +1182,6 @@ static enum virtio_device_endian virtio_current_cpu_endian(void)
}
}
static void virtio_virtqueue_reset_region_cache(struct VirtQueue *vq)
{
VRingMemoryRegionCaches *caches;
caches = atomic_read(&vq->vring.caches);
atomic_rcu_set(&vq->vring.caches, NULL);
if (caches) {
call_rcu(caches, virtio_free_region_cache, rcu);
}
}
void virtio_reset(void *opaque)
{
VirtIODevice *vdev = opaque;