diff options
Diffstat (limited to 'src/vnet/devices')
-rw-r--r-- | src/vnet/devices/tap/tap.c | 4 | ||||
-rw-r--r-- | src/vnet/devices/virtio/device.c | 2 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.c | 35 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.h | 4 |
4 files changed, 34 insertions, 11 deletions
diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index ff7bd91e8db..a7d10fe5473 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -390,7 +390,7 @@ error: close (vif->tap_fd); if (vif->fd != -1) close (vif->fd); - vec_foreach_index (i, vif->vrings) virtio_vring_free (vif, i); + vec_foreach_index (i, vif->vrings) virtio_vring_free (vm, vif, i); memset (vif, 0, sizeof (virtio_if_t)); pool_put (vim->interfaces, vif); @@ -429,7 +429,7 @@ tap_delete_if (vlib_main_t * vm, u32 sw_if_index) if (vif->fd != -1) close (vif->fd); - vec_foreach_index (i, vif->vrings) virtio_vring_free (vif, i); + vec_foreach_index (i, vif->vrings) virtio_vring_free (vm, vif, i); vec_free (vif->vrings); hash_unset (tm->dev_instance_by_interface_id, vif->id); diff --git a/src/vnet/devices/virtio/device.c b/src/vnet/devices/virtio/device.c index df5fcf509b8..5528ddb0429 100644 --- a/src/vnet/devices/virtio/device.c +++ b/src/vnet/devices/virtio/device.c @@ -88,7 +88,7 @@ format_virtio_tx_trace (u8 * s, va_list * args) return s; } -static_always_inline void +inline void virtio_free_used_desc (vlib_main_t * vm, virtio_vring_t * vring) { u16 used = vring->desc_in_use; diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index 7829da6b1a1..3867cf03a46 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -134,20 +134,41 @@ error: return err; } +static_always_inline void +virtio_free_rx_buffers (vlib_main_t * vm, virtio_vring_t * vring) +{ + u16 used = vring->desc_in_use; + u16 next = vring->desc_next; + u16 mask = vring->size - 1; + + while (used) + { + vlib_buffer_free (vm, &vring->buffers[next], 1); + next = (next + 1) & mask; + used--; + } +} + clib_error_t * -virtio_vring_free (virtio_if_t * vif, u32 idx) +virtio_vring_free (vlib_main_t * vm, virtio_if_t * vif, u32 idx) { - //TODO free buffers and indirect descriptor allocs virtio_vring_t *vring = vec_elt_at_index (vif->vrings, idx); + + clib_file_del_by_index (&file_main, vring->call_file_index); + close (vring->kick_fd); + close (vring->call_fd); + if (vring->used) + { + if ((idx & 1) == 1) + virtio_free_used_desc (vm, vring); + else + virtio_free_rx_buffers (vm, vring); + clib_mem_free (vring->used); + } if (vring->desc) clib_mem_free (vring->desc); if (vring->avail) clib_mem_free (vring->avail); - if (vring->used) - clib_mem_free (vring->used); - clib_file_del_by_index (&file_main, vring->call_file_index); - close (vring->kick_fd); - close (vring->call_fd); vec_free (vring->buffers); return 0; } diff --git a/src/vnet/devices/virtio/virtio.h b/src/vnet/devices/virtio/virtio.h index 079223d233e..90eeb536ab1 100644 --- a/src/vnet/devices/virtio/virtio.h +++ b/src/vnet/devices/virtio/virtio.h @@ -128,7 +128,9 @@ extern vlib_node_registration_t virtio_input_node; clib_error_t *virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz); -clib_error_t *virtio_vring_free (virtio_if_t * vif, u32 idx); +clib_error_t *virtio_vring_free (vlib_main_t * vm, virtio_if_t * vif, + u32 idx); +extern void virtio_free_used_desc (vlib_main_t * vm, virtio_vring_t * vring); #endif /* _VNET_DEVICES_VIRTIO_VIRTIO_H_ */ |