61 s =
format (s,
"current data %d, length %d, free-list %d",
97 t =
"known-allocated";
109 return format (s,
"%s", t);
132 uword follow_buffer_next,
133 uword ** unique_hash)
151 return format (0,
"%d-%d beyond end of buffer %d",
156 if (follow_buffer_next
164 return format (0,
"next 0x%x: %U",
195 uword next_buffer_stride,
198 uword follow_buffer_next)
201 u32 bi, * b = buffers;
203 u8 * msg = 0, * result = 0;
206 for (i = 0; i < n_buffers; i++)
209 b += next_buffer_stride;
214 msg =
format (0,
"not unique");
219 if (k != known_state)
221 msg =
format (0,
"is %U; expected %U",
237 result =
format (0,
"0x%x: %v", bi, msg);
264 ASSERT(vm == vlib_mains[0]);
268 for (i = 0; i < n_buffers; i++)
275 if (known != expected_state)
279 (vm,
"%s %U buffer 0x%x",
280 is_free ?
"freeing" :
"allocating",
301 ASSERT (n_bytes %
sizeof (dst[0]) == 0);
308 while (n_bytes >= 4 *
sizeof (dst[0]))
312 n_bytes -= 4 *
sizeof (dst[0]);
326 while (n_bytes >= 8 *
sizeof (dst[0]))
330 n_bytes -= 8 *
sizeof (dst[0]);
349 n_bytes -= 1 *
sizeof (dst[0]);
353 #define BUFFERS_PER_COPY (sizeof (vlib_copy_unit_t) / sizeof (u32)) 359 uword n_unaligned_buffers)
367 ASSERT (la >= n_unaligned_buffers);
369 while (lu < n_unaligned_buffers)
444 return p ? p[0] : ~0;
460 u32 default_free_free_list_index;
462 default_free_free_list_index =
471 return default_free_free_list_index;
476 memset (f, 0,
sizeof (f[0]));
558 if (merge_index != ~0 && merge_index != free_list_index)
567 memset (f, 0xab,
sizeof (f[0]));
576 uword min_free_buffers)
581 u32 n_remaining, n_alloc, n_this_chunk;
588 return min_free_buffers;
598 while (n_remaining > 0)
600 n_this_chunk =
clib_min (n_remaining, 16);
602 n_bytes = n_this_chunk * (
sizeof (b[0]) + fl->
n_data_bytes);
614 n_alloc += n_this_chunk;
615 n_remaining -= n_this_chunk;
620 for (i = 0; i < n_this_chunk; i++)
629 memset (buffers, 0, n_bytes);
633 for (i = 0; i < n_this_chunk; i++)
657 uword n_unaligned_start, n_unaligned_end, n_filled;
661 n_left = n_alloc_buffers;
670 n_left = n_filled < n_left ? n_filled : n_left;
671 n_alloc_buffers = n_left;
673 if (n_unaligned_start >= n_left)
675 n_unaligned_start = n_left;
681 fill_unaligned (vm, free_list, n_unaligned_start + n_unaligned_end);
686 if (n_unaligned_start)
688 uword n_copy = n_unaligned_start;
746 ASSERT (n_unaligned_end == n_left);
764 return n_alloc_buffers;
796 u32 buffer_index,
u8 do_init)
831 u32 follow_buffer_next)
835 static u32 * next_to_free[2];
836 u32 i_next_to_free, * b, * n, * f, fi;
842 u8 free0, free1=0, free_next0, free_next1;
844 u32 follow_buffer_next);
851 n_buffers = (*cb)(vm, buffers, n_buffers, follow_buffer_next);
858 u32 bi0 = buffers[0];
883 n = next_to_free[i_next_to_free];
886 vlib_buffer_t * b0, * b1, * binit0, * binit1, dummy_buffers[2];
908 if (follow_buffer_next)
919 free_next0 = free_next1 = 0;
928 binit0 = free0 ? b0 : &dummy_buffers[0];
929 binit1 = free1 ? b1 : &dummy_buffers[1];
937 n -= free_next0 + free_next1;
948 for (i = 0; i <
vec_len (announce_list); i++)
949 if (fl0 == announce_list[i])
954 if (
PREDICT_FALSE(fl1->buffers_added_to_freelist_function != 0))
957 for (i = 0; i <
vec_len (announce_list); i++)
958 if (fl1 == announce_list[i])
967 if (fi0 != fi && fi1 != fi)
992 if (follow_buffer_next)
1007 binit0 = free0 ? b0 : &dummy_buffers[0];
1025 for (i = 0; i <
vec_len (announce_list); i++)
1026 if (fl0 == announce_list[i])
1039 if (follow_buffer_next && ((n_left = n - next_to_free[i_next_to_free]) > 0))
1041 b = next_to_free[i_next_to_free];
1042 i_next_to_free ^= 1;
1051 for (i = 0; i <
vec_len (announce_list); i++)
1053 fl = announce_list[
i];
1056 _vec_len(announce_list) = 0;
1085 for (i = 0; i < n_buffers; i++)
1096 uword n_packet_data_bytes,
1097 uword min_n_buffers_each_physmem_alloc,
1109 memset (t, 0,
sizeof (t[0]));
1115 (vm, n_packet_data_bytes,
1170 u32 free_list_index,
1172 void * data,
u32 n_data_bytes)
1174 u32 n_buffer_bytes, n_left, n_left_this_buffer, bi;
1181 goto out_of_buffers;
1184 n_left = n_data_bytes;
1200 n =
clib_min (n_left_this_buffer, n_left);
1209 goto out_of_buffers;
1225 u32 free_list_index,
1228 void * data,
u16 data_len) {
1242 u16 len = (data_len > max)?max:data_len;
1263 uword n, n_bytes_to_write;
1270 ASSERT (sm->
tx.max_n_data_bytes_per_chain > 0);
1272 || sm->
tx.n_total_data_bytes + n_bytes_to_write > sm->
tx.max_n_data_bytes_per_chain)
1282 sm->
tx.n_total_data_bytes = 0;
1296 if (n_bytes_to_write > 0)
1302 sm->
tx.n_total_data_bytes += n_bytes_to_write;
1371 memset (m, 0,
sizeof (m[0]));
1374 _vec_len (save) = 0;
1381 sm->
tx.n_total_data_bytes = 0;
1430 uword bytes_alloc, bytes_free, n_free,
size;
1433 return format (s,
"%=30s%=12s%=12s%=12s%=12s%=12s%=12s",
1434 "Name",
"Index",
"Size",
"Alloc",
"Free",
"#Alloc",
"#Free");
1438 bytes_alloc = size * f->
n_alloc;
1439 bytes_free = size * n_free;
1441 s =
format (s,
"%30s%12d%12d%=12U%=12U%=12d%=12d",
1460 vlib_cli_output (vm,
"%U", format_vlib_buffer_free_list, f);
1467 .path =
"show buffers",
1468 .short_help =
"Show packet buffer allocation",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
always_inline uword round_pow2(uword x, uword pow2)
#define hash_set(h, key, value)
sll srl srl sll sra u16x4 i
always_inline void add_buffer_to_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f, u32 buffer_index, u8 do_init)
always_inline uword vlib_process_create_one_time_event(vlib_main_t *vm, uword node_index, uword with_type_opaque)
static void vlib_buffer_validate_alloc_free(vlib_main_t *vm, u32 *buffers, uword n_buffers, vlib_buffer_known_state_t expected_state)
static void del_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f)
vlib_node_runtime_t node_runtime
void * vlib_packet_template_get_packet(vlib_main_t *vm, vlib_packet_template_t *t, u32 *bi_result)
u8 * vlib_validate_buffer(vlib_main_t *vm, u32 bi, uword follow_buffer_next)
void unserialize_close_vlib_buffer(serialize_main_t *m)
always_inline u32 vlib_buffer_get_free_list_with_size(vlib_main_t *vm, u32 size)
u32 free_list_index
Buffer free list that this buffer was allocated from and will be freed to.
vlib_physmem_main_t physmem_main
serialize_main_header_t header
u8 * format_vlib_buffer(u8 *s, va_list *args)
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
vlib_buffer_t buffer_init_template
struct vlib_main_t * vlib_main
static uword fill_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *fl, uword min_free_buffers)
#define clib_error(format, args...)
void vlib_packet_template_get_packet_helper(vlib_main_t *vm, vlib_packet_template_t *t)
void *(* os_physmem_alloc_aligned)(vlib_physmem_main_t *pm, uword n_bytes, uword alignment)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
void ** buffer_memory_allocated
vlib_buffer_main_t * buffer_main
always_inline vlib_buffer_t * vlib_buffer_chain_buffer(vlib_main_t *vm, vlib_buffer_t *first, vlib_buffer_t *last, u32 next_bi)
u32 min_n_buffers_each_physmem_alloc
always_inline uword copy_alignment(u32 *x)
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
always_inline u32 vlib_buffer_free_list_buffer_size(vlib_main_t *vm, u32 free_list_index)
uword vlib_buffer_length_in_chain_slow_path(vlib_main_t *vm, vlib_buffer_t *b_first)
struct vlib_serialize_buffer_main_t::@27::@30 rx
always_inline void vlib_buffer_init_two_for_free_list(vlib_buffer_t *_dst0, vlib_buffer_t *_dst1, vlib_buffer_free_list_t *fl)
void vnet_buffer_free_dpdk_mb(vlib_buffer_t *b)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
#define vec_add1_aligned(V, E, A)
Add 1 element to end of vector (alignment specified).
void(* buffers_added_to_freelist_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define static_always_inline
#define pool_foreach(VAR, POOL, BODY)
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
always_inline heap_elt_t * last(heap_header_t *h)
void vlib_buffer_free_no_next(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers, does not free the buffer chain for each buffer.
static clib_error_t * show_buffers(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
always_inline uword pool_elts(void *v)
always_inline uword clib_fifo_elts(void *v)
static u32 alloc_from_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *free_list, u32 *alloc_buffers, u32 n_alloc_buffers)
always_inline vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, u32 free_list_index)
#define vec_end(v)
End (last data address) of vector.
static uword pointer_to_uword(const void *p)
u32 serialize_close_vlib_buffer(serialize_main_t *m)
#define VLIB_BUFFER_NEXT_PRESENT
always_inline void serialize_error(serialize_main_header_t *m, clib_error_t *error)
always_inline heap_elt_t * first(heap_header_t *h)
static void serialize_open_vlib_helper(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm, uword is_read)
static u8 * format_vlib_buffer_known_state(u8 *s, va_list *args)
always_inline vlib_buffer_known_state_t vlib_buffer_is_known(vlib_main_t *vm, u32 buffer_index)
#define VLIB_BUFFER_PRE_DATA_SIZE
always_inline void vlib_buffer_free_one(vlib_main_t *vm, u32 buffer_index)
Free one buffer Shorthand to free a single buffer chain.
static void vlib_packet_template_buffer_init(vlib_main_t *vm, vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
always_inline uword serialize_stream_is_end_of_stream(serialize_stream_t *s)
#define pool_elt_at_index(p, i)
always_inline void vlib_buffer_chain_increase_length(vlib_buffer_t *first, vlib_buffer_t *last, i32 len)
always_inline void clib_fifo_reset(void *v)
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
#define clib_fifo_sub1(f, e)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES
u16 current_length
Nbytes between current data and the end of this buffer.
uword os_get_cpu_number(void)
always_inline uword vlib_process_wait_for_one_time_event(vlib_main_t *vm, uword **data_vector, uword with_type_index)
u32 vlib_buffer_alloc_from_free_list(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 free_list_index)
Allocate buffers from specific freelist into supplied array.
#define clib_error_create(args...)
u32 vlib_buffer_add_data(vlib_main_t *vm, u32 free_list_index, u32 buffer_index, void *data, u32 n_data_bytes)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
u32 vlib_buffer_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
#define uword_to_pointer(u, type)
#define pool_get_aligned(P, E, A)
#define vec_add_aligned(V, E, N, A)
Add N elements to end of vector V (no header, specified alignment)
u16 vlib_buffer_chain_append_data_with_alloc(vlib_main_t *vm, u32 free_list_index, vlib_buffer_t *first, vlib_buffer_t **last, void *data, u16 data_len)
serialize_stream_t stream
u32(* buffer_free_callback)(struct vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
#define CLIB_PREFETCH(addr, size, type)
#define vec_free(V)
Free vector's memory (no header).
#define clib_memcpy(a, b, c)
serialize_data_function_t * data_function
#define VLIB_BUFFER_TOTAL_LENGTH_VALID
#define pool_is_free_index(P, I)
vlib_buffer_known_state_t
uword data_function_opaque
static u8 * vlib_validate_buffer_helper(vlib_main_t *vm, u32 bi, uword follow_buffer_next, uword **unique_hash)
#define VLIB_CLI_COMMAND(x,...)
#define hash_set1(h, key)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
#define hash_create(elts, value_bytes)
void vlib_packet_template_init(vlib_main_t *vm, vlib_packet_template_t *t, void *packet_data, uword n_packet_data_bytes, uword min_n_buffers_each_physmem_alloc, char *fmt,...)
u32 vlib_buffer_get_or_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
static_always_inline void vlib_buffer_free_inline(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
static u32 vlib_buffer_create_free_list_helper(vlib_main_t *vm, u32 n_data_bytes, u32 is_public, u32 is_default, u8 *name)
vhost_vring_state_t state
static u8 * format_vlib_buffer_free_list(u8 *s, va_list *va)
u32 next_buffer
Next buffer for this linked-list of buffers.
void vlib_aligned_memcpy(void *_dst, void *_src, int n_bytes)
u32 clone_count
Specifies whether this buffer should be reinitialized when freed.
static void trim_aligned(vlib_buffer_free_list_t *f)
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
always_inline vlib_buffer_free_list_t * buffer_get_free_list(vlib_main_t *vm, vlib_buffer_t *b, u32 *index)
#define VLIB_BUFFER_IS_TRACED
always_inline void vlib_buffer_init_for_free_list(vlib_buffer_t *_dst, vlib_buffer_free_list_t *fl)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
u8 * vlib_validate_buffers(vlib_main_t *vm, u32 *buffers, uword next_buffer_stride, uword n_buffers, vlib_buffer_known_state_t known_state, uword follow_buffer_next)
always_inline uword clib_mem_is_heap_object(void *p)
always_inline void vlib_buffer_set_known_state(vlib_main_t *vm, u32 buffer_index, vlib_buffer_known_state_t state)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void(* buffer_init_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
vlib_buffer_free_list_t * buffer_free_list_pool
static void vlib_serialize_tx(serialize_main_header_t *m, serialize_stream_t *s)
always_inline void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
u8 * format_vlib_buffer_and_data(u8 *s, va_list *args)
always_inline uword vlib_current_process(vlib_main_t *vm)
always_inline vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
always_inline vlib_buffer_t * vlib_buffer_next_contiguous(vlib_buffer_t *b, u32 buffer_bytes)
always_inline u32 vlib_buffer_round_size(u32 size)
u8 * format_vlib_buffer_contents(u8 *s, va_list *va)
uword buffer_init_function_opaque
void vlib_buffer_chain_validate(vlib_main_t *vm, vlib_buffer_t *b_first)
static void merge_free_lists(vlib_buffer_free_list_t *dst, vlib_buffer_free_list_t *src)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
void(* os_physmem_free)(void *x)
static void fill_unaligned(vlib_main_t *vm, vlib_buffer_free_list_t *free_list, uword n_unaligned_buffers)
u32 min_n_buffers_each_physmem_alloc
void unserialize_open_vlib_buffer(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
void serialize_open_vlib_buffer(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
always_inline u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
u32 trace_index
Specifies index into trace buffer if VLIB_PACKET_IS_TRACED flag is set.
uword * free_list_by_size
vlib_main_t ** vlib_mains
#define vlib_panic_with_msg(vm, args...)
void * vlib_set_buffer_free_callback(vlib_main_t *vm, void *fp)
void vlib_buffer_delete_free_list(vlib_main_t *vm, u32 free_list_index)
struct vlib_serialize_buffer_main_t::@27::@29 tx
static void vlib_serialize_rx(serialize_main_header_t *m, serialize_stream_t *s)