From 8f36e4a3f8e647796c273f82325a9ba4738ea49a Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 11 Jan 2018 09:02:01 -0800 Subject: vlib_buffer_clone: allow client to request the maximum number of clones; 256 Change-Id: Id96dc5d86719546268b50a9999a06387d2d9075c Signed-off-by: Neale Ranns --- src/vlib/buffer_funcs.h | 62 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h index cc56db7762c..b73fb266d64 100644 --- a/src/vlib/buffer_funcs.h +++ b/src/vlib/buffer_funcs.h @@ -585,27 +585,28 @@ vlib_buffer_copy (vlib_main_t * vm, vlib_buffer_t * b) return fd; } -/** \brief Create multiple clones of buffer and store them in the supplied array +/** \brief Create a maximum of 256 clones of buffer and store them + in the supplied array @param vm - (vlib_main_t *) vlib main data structure pointer @param src_buffer - (u32) source buffer index @param buffers - (u32 * ) buffer index array - @param n_buffers - (u8) number of buffer clones requested + @param n_buffers - (u16) number of buffer clones requested (<=256) @param head_end_offset - (u16) offset relative to current position where packet head ends - @return - (u8) number of buffers actually cloned, may be + @return - (u16) number of buffers actually cloned, may be less than the number requested or zero */ - -always_inline u8 -vlib_buffer_clone (vlib_main_t * vm, u32 src_buffer, u32 * buffers, - u8 n_buffers, u16 head_end_offset) +always_inline u16 +vlib_buffer_clone_256 (vlib_main_t * vm, u32 src_buffer, u32 * buffers, + u16 n_buffers, u16 head_end_offset) { - u8 i; + u16 i; vlib_buffer_t *s = vlib_get_buffer (vm, src_buffer); ASSERT (s->n_add_refs == 0); ASSERT (n_buffers); + ASSERT (n_buffers <= 256); if (s->current_length <= head_end_offset + CLIB_CACHE_LINE_BYTES * 2) { @@ -622,15 +623,16 @@ vlib_buffer_clone (vlib_main_t * vm, u32 src_buffer, u32 * buffers, return n_buffers; } - n_buffers = vlib_buffer_alloc_from_free_list (vm, buffers, n_buffers, - vlib_buffer_get_free_list_index - (s)); - if (PREDICT_FALSE (n_buffers == 0)) + if (PREDICT_FALSE (n_buffers == 1)) { buffers[0] = src_buffer; return 1; } + n_buffers = vlib_buffer_alloc_from_free_list (vm, buffers, n_buffers, + vlib_buffer_get_free_list_index + (s)); + for (i = 0; i < n_buffers; i++) { vlib_buffer_t *d = vlib_get_buffer (vm, buffers[i]); @@ -659,6 +661,42 @@ vlib_buffer_clone (vlib_main_t * vm, u32 src_buffer, u32 * buffers, return n_buffers; } +/** \brief Create multiple clones of buffer and store them + in the supplied array + + @param vm - (vlib_main_t *) vlib main data structure pointer + @param src_buffer - (u32) source buffer index + @param buffers - (u32 * ) buffer index array + @param n_buffers - (u16) number of buffer clones requested (<=256) + @param head_end_offset - (u16) offset relative to current position + where packet head ends + @return - (u16) number of buffers actually cloned, may be + less than the number requested or zero +*/ +always_inline u16 +vlib_buffer_clone (vlib_main_t * vm, u32 src_buffer, u32 * buffers, + u16 n_buffers, u16 head_end_offset) +{ + vlib_buffer_t *s = vlib_get_buffer (vm, src_buffer); + u16 n_cloned = 0; + + while (n_buffers > 256) + { + vlib_buffer_t *copy; + copy = vlib_buffer_copy (vm, s); + n_cloned += vlib_buffer_clone_256 (vm, + vlib_get_buffer_index (vm, copy), + (buffers + n_cloned), + 256, head_end_offset); + n_buffers -= 256; + } + n_cloned += vlib_buffer_clone_256 (vm, src_buffer, + buffers + n_cloned, + n_buffers, head_end_offset); + + return n_cloned; +} + /** \brief Attach cloned tail to the buffer @param vm - (vlib_main_t *) vlib main data structure pointer -- cgit 1.2.3-korg