mirror of https://gitee.com/openkylin/qemu.git
dataplane: do not free VirtQueueElement in vring_push()
VirtQueueElement is allocated in vring_pop() so it seems to make sense that vring_push() should free it. Alas, virtio-blk frees VirtQueueElement itself in virtio_blk_free_request(). This patch solves a double-free assertion in glib's g_slice_free(). Rename vring_free_element() to vring_unmap_element() since it no longer frees the VirtQueueElement. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Tested-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
0a21ea3289
commit
abd764250f
|
@ -272,7 +272,7 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void vring_free_element(VirtQueueElement *elem)
|
||||
static void vring_unmap_element(VirtQueueElement *elem)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -287,8 +287,6 @@ void vring_free_element(VirtQueueElement *elem)
|
|||
for (i = 0; i < elem->in_num; i++) {
|
||||
vring_unmap(elem->in_sg[i].iov_base, true);
|
||||
}
|
||||
|
||||
g_slice_free(VirtQueueElement, elem);
|
||||
}
|
||||
|
||||
/* This looks in the virtqueue and for the first available buffer, and converts
|
||||
|
@ -402,7 +400,8 @@ out:
|
|||
vring->broken = true;
|
||||
}
|
||||
if (elem) {
|
||||
vring_free_element(elem);
|
||||
vring_unmap_element(elem);
|
||||
g_slice_free(VirtQueueElement, elem);
|
||||
}
|
||||
*p_elem = NULL;
|
||||
return ret;
|
||||
|
@ -418,7 +417,7 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int len)
|
|||
unsigned int head = elem->index;
|
||||
uint16_t new;
|
||||
|
||||
vring_free_element(elem);
|
||||
vring_unmap_element(elem);
|
||||
|
||||
/* Don't touch vring if a fatal error occurred */
|
||||
if (vring->broken) {
|
||||
|
|
|
@ -55,6 +55,5 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring *vring);
|
|||
bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
|
||||
int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement **elem);
|
||||
void vring_push(Vring *vring, VirtQueueElement *elem, int len);
|
||||
void vring_free_element(VirtQueueElement *elem);
|
||||
|
||||
#endif /* VRING_H */
|
||||
|
|
Loading…
Reference in New Issue