i = sizeof (struct vring_desc) * sz;
i = round_pow2 (i, CLIB_CACHE_LINE_BYTES);
vring->desc = clib_mem_alloc_aligned (i, CLIB_CACHE_LINE_BYTES);
- memset (vring->desc, 0, i);
+ clib_memset (vring->desc, 0, i);
i = sizeof (struct vring_avail) + sz * sizeof (vring->avail->ring[0]);
i = round_pow2 (i, CLIB_CACHE_LINE_BYTES);
vring->avail = clib_mem_alloc_aligned (i, CLIB_CACHE_LINE_BYTES);
- memset (vring->avail, 0, i);
+ clib_memset (vring->avail, 0, i);
// tell kernel that we don't need interrupt
vring->avail->flags = VIRTIO_RING_FLAG_MASK_INT;
i = sizeof (struct vring_used) + sz * sizeof (struct vring_used_elem);
i = round_pow2 (i, CLIB_CACHE_LINE_BYTES);
vring->used = clib_mem_alloc_aligned (i, CLIB_CACHE_LINE_BYTES);
- memset (vring->used, 0, i);
+ clib_memset (vring->used, 0, i);
ASSERT (vring->buffers == 0);
- vec_validate_aligned (vring->buffers, sz * 2, CLIB_CACHE_LINE_BYTES);
+ vec_validate_aligned (vring->buffers, sz, CLIB_CACHE_LINE_BYTES);
vring->size = sz;
vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
t.read_function = call_read_ready;
t.file_descriptor = vring->call_fd;
t.private_data = vif->dev_instance << 16 | idx;
+ t.description = format (0, "%U vring %u", format_virtio_device_name,
+ vif->dev_instance, idx);
vring->call_file_index = clib_file_add (&file_main, &t);
state.index = idx;
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 last = vring->last_used_idx;
+ u16 mask = vring->size - 1;
+
+ while (used)
+ {
+ vlib_buffer_free (vm, &vring->buffers[last & mask], 1);
+ last++;
+ 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;
}