vlib_buffer_clone: allow client to request the maximum number of clones; 256
Change-Id: Id96dc5d86719546268b50a9999a06387d2d9075c
Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
diff --git a/src/vlib/buffer_funcs.h b/src/vlib/buffer_funcs.h
index cc56db7..b73fb26 100644
--- a/src/vlib/buffer_funcs.h
+++ b/src/vlib/buffer_funcs.h
@@ -585,27 +585,28 @@
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 @@
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 @@
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