diff options
-rw-r--r-- | src/vlib/buffer_funcs.h | 29 | ||||
-rw-r--r-- | src/vnet/devices/virtio/node.c | 13 | ||||
-rw-r--r-- | src/vnet/devices/virtio/virtio.c | 2 |
3 files changed, 33 insertions, 11 deletions
diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h index 1ea3c0829b8..06cc6dac61e 100644 --- a/src/vlib/buffer_funcs.h +++ b/src/vlib/buffer_funcs.h @@ -344,6 +344,35 @@ vlib_buffer_alloc (vlib_main_t * vm, u32 * buffers, u32 n_buffers) VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX); } +/** \brief Allocate buffers into ring + + @param vm - (vlib_main_t *) vlib main data structure pointer + @param buffers - (u32 * ) buffer index ring + @param start - (u32) first slot in the ring + @param ring_size - (u32) ring size + @param n_buffers - (u32) number of buffers requested + @return - (u32) number of buffers actually allocated, may be + less than the number requested or zero +*/ +always_inline u32 +vlib_buffer_alloc_to_ring (vlib_main_t * vm, u32 * ring, u32 start, + u32 ring_size, u32 n_buffers) +{ + u32 n_alloc; + + ASSERT (n_buffers <= ring_size); + + if (PREDICT_TRUE (start + n_buffers <= ring_size)) + return vlib_buffer_alloc (vm, ring + start, n_buffers); + + n_alloc = vlib_buffer_alloc (vm, ring + start, ring_size - start); + + if (PREDICT_TRUE (n_alloc == ring_size - start)) + n_alloc += vlib_buffer_alloc (vm, ring, n_buffers - n_alloc); + + return n_alloc; +} + /** \brief Free buffers Frees the entire buffer chain for each buffer diff --git a/src/vnet/devices/virtio/node.c b/src/vnet/devices/virtio/node.c index 5ca06366cad..9477a1cfc58 100644 --- a/src/vnet/devices/virtio/node.c +++ b/src/vnet/devices/virtio/node.c @@ -83,10 +83,9 @@ static_always_inline void virtio_refill_vring (vlib_main_t * vm, virtio_vring_t * vring) { const int hdr_sz = sizeof (struct virtio_net_hdr_v1); - u16 used, next, avail, n_slots, n_alloc; + u16 used, next, avail, n_slots; u16 sz = vring->size; u16 mask = sz - 1; - int i; used = vring->desc_in_use; @@ -96,14 +95,8 @@ virtio_refill_vring (vlib_main_t * vm, virtio_vring_t * vring) n_slots = sz - used; next = vring->desc_next; avail = vring->avail->idx; - n_alloc = vlib_buffer_alloc (vm, &vring->buffers[next], n_slots); - - if (PREDICT_FALSE (n_alloc < n_slots)) - n_slots = n_alloc; - - i = next + n_slots - sz; - if (PREDICT_FALSE (i > 0)) - clib_memcpy (vring->buffers, &vring->buffers[sz], i * sizeof (u32)); + n_slots = vlib_buffer_alloc_to_ring (vm, vring->buffers, next, vring->size, + n_slots); while (n_slots) { diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index 3867cf03a46..02ded3f5f52 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -100,7 +100,7 @@ virtio_vring_init (vlib_main_t * vm, virtio_if_t * vif, u16 idx, u16 sz) 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); |