mirror of https://github.com/xemu-project/xemu.git
virtio: free MemoryRegionCache when initialization fails
This commit is contained in:
parent
e40077fd2c
commit
45641dba38
|
@ -123,11 +123,22 @@ static void virtio_free_region_cache(VRingMemoryRegionCaches *caches)
|
||||||
g_free(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)
|
static void virtio_init_region_cache(VirtIODevice *vdev, int n)
|
||||||
{
|
{
|
||||||
VirtQueue *vq = &vdev->vq[n];
|
VirtQueue *vq = &vdev->vq[n];
|
||||||
VRingMemoryRegionCaches *old = vq->vring.caches;
|
VRingMemoryRegionCaches *old = vq->vring.caches;
|
||||||
VRingMemoryRegionCaches *new;
|
VRingMemoryRegionCaches *new = NULL;
|
||||||
hwaddr addr, size;
|
hwaddr addr, size;
|
||||||
int event_size;
|
int event_size;
|
||||||
int64_t len;
|
int64_t len;
|
||||||
|
@ -136,7 +147,7 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n)
|
||||||
|
|
||||||
addr = vq->vring.desc;
|
addr = vq->vring.desc;
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
return;
|
goto out_no_cache;
|
||||||
}
|
}
|
||||||
new = g_new0(VRingMemoryRegionCaches, 1);
|
new = g_new0(VRingMemoryRegionCaches, 1);
|
||||||
size = virtio_queue_get_desc_size(vdev, n);
|
size = virtio_queue_get_desc_size(vdev, n);
|
||||||
|
@ -170,11 +181,14 @@ static void virtio_init_region_cache(VirtIODevice *vdev, int n)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_avail:
|
err_avail:
|
||||||
address_space_cache_destroy(&new->used);
|
address_space_cache_destroy(&new->avail);
|
||||||
err_used:
|
err_used:
|
||||||
address_space_cache_destroy(&new->desc);
|
address_space_cache_destroy(&new->used);
|
||||||
err_desc:
|
err_desc:
|
||||||
|
address_space_cache_destroy(&new->desc);
|
||||||
|
out_no_cache:
|
||||||
g_free(new);
|
g_free(new);
|
||||||
|
virtio_virtqueue_reset_region_cache(vq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virt queue functions */
|
/* 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)
|
void virtio_reset(void *opaque)
|
||||||
{
|
{
|
||||||
VirtIODevice *vdev = opaque;
|
VirtIODevice *vdev = opaque;
|
||||||
|
|
Loading…
Reference in New Issue