68 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
74 b_first->
flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
85 #define _(bit, name, v) \ 86 if (v && (b->flags & VLIB_BUFFER_##name)) \ 87 a = format (a, "%s ", v); 90 s =
format (s,
"current data %d, length %d, free-list %d, clone-count %u",
94 if (b->
flags & VLIB_BUFFER_TOTAL_LENGTH_VALID)
95 s =
format (s,
", totlen-nifb %d",
98 if (b->
flags & VLIB_BUFFER_IS_TRACED)
105 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
112 format (s,
"\n%Unext-buffer 0x%x, segment length %d, clone-count %u",
145 t =
"known-allocated";
157 return format (s,
"%s", t);
169 if (!(b->
flags & VLIB_BUFFER_NEXT_PRESENT))
180 uword follow_buffer_next,
uword ** unique_hash)
187 return format (0,
"unknown free list 0x%x",
198 return format (0,
"%d-%d beyond end of buffer %d",
201 if (follow_buffer_next && (b->
flags & VLIB_BUFFER_NEXT_PRESENT))
208 return format (0,
"next 0x%x: %U",
241 uword next_buffer_stride,
244 uword follow_buffer_next)
247 u32 bi, *b = buffers;
249 u8 *msg = 0, *result = 0;
252 for (i = 0; i < n_buffers; i++)
255 b += next_buffer_stride;
260 msg =
format (0,
"not unique");
265 if (k != known_state)
267 msg =
format (0,
"is %U; expected %U",
283 result =
format (0,
"0x%x: %v", bi, msg);
302 } __attribute__ ((packed)) __bootstrap_vlib_main_vector
327 if (vlib_buffer_callbacks)
332 for (i = 0; i < n_buffers; i++)
339 if (known != expected_state)
343 (vm,
"%s %U buffer 0x%x",
344 is_free ?
"freeing" :
"allocating",
370 default_free_free_list_index =
378 ASSERT (default_free_free_list_index ==
382 return default_free_free_list_index;
407 for (i = 1; i <
vec_len (vlib_mains); i++)
474 for (i = 1; i <
vec_len (vlib_mains); i++)
494 uword min_free_buffers)
505 return min_free_buffers;
515 _vec_len (bp->
buffers) = n_left;
519 return min_free_buffers;
590 while (follow_buffer_next && (flags & VLIB_BUFFER_NEXT_PRESENT));
595 u32 * buffers,
u32 n_buffers,
u32 follow_buffer_next)
601 u32 follow_buffer_next);
606 n_buffers = (*cb) (
vm, buffers, n_buffers, follow_buffer_next);
611 while (i + 11 < n_buffers)
640 while (i < n_buffers)
668 uword n_packet_data_bytes,
669 uword min_n_buffers_each_alloc,
char *fmt, ...)
711 u32 * buffer_index,
void *data,
u32 n_data_bytes)
713 u32 n_buffer_bytes, n_left, n_left_this_buffer, bi;
723 n_left = n_data_bytes;
727 b->
flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;
730 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
740 n =
clib_min (n_left_this_buffer, n_left);
754 b->
flags |= VLIB_BUFFER_NEXT_PRESENT;
793 u16 len = (data_len > max) ? max : data_len;
817 else if (start < bm->buffer_mem_start)
834 clib_panic (
"buffer memory size out of range!");
850 u32 threadnum = va_arg (*va,
u32);
851 uword bytes_alloc, bytes_free, n_free,
size;
854 return format (s,
"%=7s%=30s%=12s%=12s%=12s%=12s%=12s%=12s",
855 "Thread",
"Name",
"Index",
"Size",
"Alloc",
"Free",
860 bytes_alloc = size * f->
n_alloc;
861 bytes_free = size * n_free;
863 s =
format (s,
"%7d%30v%12d%12d%=12U%=12U%=12d%=12d", threadnum,
883 curr_vm = vlib_mains[vm_index];
887 vlib_cli_output (vm,
"%U", format_vlib_buffer_free_list, f, vm_index);
893 while (vm_index <
vec_len (vlib_mains));
900 .path =
"show buffers",
901 .short_help =
"Show packet buffer allocation",
911 u32 physmem_map_index;
913 int log2_page_size = 0;
917 if (vlib_buffer_callbacks)
936 vlib_buffer_physmem_sz,
941 if (error && log2_page_size == 0)
945 vlib_log_warn (buffer_log_default,
"falling back to non-hugepage " 946 "backed buffer pool");
970 if (
unformat (input,
"memory-size-in-mb %d", &size_in_mb))
971 vlib_buffer_physmem_sz = size_in_mb << 20;
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
vlib_main_t vlib_global_main
u8 * format_clib_error(u8 *s, va_list *va)
#define hash_set(h, key, value)
#define vlib_log_warn(...)
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
static clib_error_t * vlib_buffers_configure(vlib_main_t *vm, unformat_input_t *input)
static vlib_buffer_free_list_index_t vlib_buffer_create_free_list_helper(vlib_main_t *vm, u32 n_data_bytes, u32 is_public, u32 is_default, u8 *name)
u8 vlib_buffer_register_physmem_map(vlib_main_t *vm, u32 physmem_map_index)
u16 vlib_buffer_chain_append_data_with_alloc(vlib_main_t *vm, vlib_buffer_free_list_index_t free_list_index, vlib_buffer_t *first, vlib_buffer_t **last, void *data, u16 data_len)
vlib_buffer_callbacks_t cb
#define CLIB_PMALLOC_NUMA_LOCAL
#define clib_memcpy_fast(a, b, c)
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
static void vlib_buffer_chain_increase_length(vlib_buffer_t *first, vlib_buffer_t *last, i32 len)
vlib_buffer_t buffer_init_template
#define VLIB_BUFFER_PRE_DATA_SIZE
#define CLIB_LOG2_CACHE_LINE_BYTES
static heap_elt_t * last(heap_header_t *h)
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static void vlib_buffer_free_no_next_internal(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
vlib_physmem_map_t * vlib_physmem_get_map(vlib_main_t *vm, u32 index)
static clib_error_t * show_buffers(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vlib_buffer_free_list_index_t index
static uword min_log2(uword x)
uword vlib_buffer_length_in_chain_slow_path(vlib_main_t *vm, vlib_buffer_t *b_first)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define vlib_worker_thread_barrier_sync(X)
static vlib_log_class_t buffer_log_default
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
static u8 * format_vlib_buffer_free_list(u8 *s, va_list *va)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define static_always_inline
static u32 vlib_buffer_physmem_sz
void * vlib_packet_template_get_packet(vlib_main_t *vm, vlib_packet_template_t *t, u32 *bi_result)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
void(* buffer_init_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
static_always_inline void * vlib_buffer_pool_get_buffer(vlib_main_t *vm, vlib_buffer_pool_t *bp)
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
vlib_buffer_free_no_next_cb_t * vlib_buffer_free_no_next_cb
#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES
vhost_vring_state_t state
u8 * format_vlib_buffer(u8 *s, va_list *args)
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
static void clib_spinlock_init(clib_spinlock_t *p)
static heap_elt_t * first(heap_header_t *h)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void * vlib_set_buffer_free_callback(vlib_main_t *vm, void *fp)
clib_error_t * vlib_physmem_shared_map_create(vlib_main_t *vm, char *name, uword size, u32 log2_page_sz, u32 numa_node, u32 *map_index)
u32 min_n_buffers_each_alloc
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_alloc, char *fmt,...)
u16 current_length
Nbytes between current data and the end of this buffer.
uword clib_mem_get_page_size(void)
void(* vlib_buffer_delete_free_list_cb)(struct vlib_main_t *vm, vlib_buffer_free_list_index_t free_list_index)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
#define pool_put(P, E)
Free an object E in pool P.
vlib_buffer_pool_t * buffer_pools
static u8 * vlib_validate_buffer_helper(vlib_main_t *vm, u32 bi, uword follow_buffer_next, uword **unique_hash)
vlib_buffer_free_list_t * buffer_free_list_pool
static void vlib_buffer_add_to_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f, u32 buffer_index, u8 do_init)
static void vlib_buffer_set_known_state(u32 buffer_index, vlib_buffer_known_state_t state)
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
#define vec_add_aligned(V, E, N, A)
Add N elements to end of vector V (no header, specified alignment)
clib_spinlock_t buffer_known_hash_lockp
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
vlib_buffer_fill_free_list_cb_t * vlib_buffer_fill_free_list_cb
static_always_inline void vlib_buffer_free_inline(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
static_always_inline uword vlib_get_thread_index(void)
u32(* buffer_free_callback)(struct vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
u8 * format_vlib_buffer_contents(u8 *s, va_list *va)
#define vec_free(V)
Free vector's memory (no header).
u8 * vlib_validate_buffer(vlib_main_t *vm, u32 bi, uword follow_buffer_next)
#define clib_warning(format, args...)
clib_error_t * vlib_buffer_main_init(struct vlib_main_t *vm)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static uword round_pow2(uword x, uword pow2)
vlib_buffer_known_state_t
#define VLIB_CLI_COMMAND(x,...)
#define hash_set1(h, key)
#define hash_create(elts, value_bytes)
void vlib_buffer_delete_free_list_internal(vlib_main_t *vm, vlib_buffer_free_list_index_t index)
vlib_buffer_free_cb_t * vlib_buffer_free_cb
static vlib_buffer_free_list_index_t vlib_buffer_get_free_list_index(vlib_buffer_t *b)
static u8 * format_vlib_buffer_known_state(u8 *s, va_list *args)
u32 next_buffer
Next buffer for this linked-list of buffers.
u8 * format_vlib_buffer_and_data(u8 *s, va_list *args)
static vlib_buffer_free_list_t * vlib_buffer_get_buffer_free_list(vlib_main_t *vm, vlib_buffer_t *b, vlib_buffer_free_list_index_t *index)
static uword pointer_to_uword(const void *p)
u8 n_add_refs
Number of additional references to this buffer.
static vlib_main_t * vlib_get_main(void)
static u32 vlib_buffer_alloc_from_free_list(vlib_main_t *vm, u32 *buffers, u32 n_buffers, vlib_buffer_free_list_index_t index)
Allocate buffers from specific freelist into supplied array.
int vlib_buffer_add_data(vlib_main_t *vm, vlib_buffer_free_list_index_t free_list_index, u32 *buffer_index, void *data, u32 n_data_bytes)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
static_always_inline void recycle_or_free(vlib_main_t *vm, vlib_buffer_main_t *bm, u32 bi, vlib_buffer_t *b, u32 follow_buffer_next)
static vlib_buffer_t * vlib_buffer_chain_buffer(vlib_main_t *vm, vlib_buffer_t *last, u32 next_bi)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 min_n_buffers_each_alloc
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
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)
static u32 vlib_buffer_free_list_buffer_size(vlib_main_t *vm, vlib_buffer_free_list_index_t index)
#define clib_error_free(e)
static void vlib_buffer_init_for_free_list(vlib_buffer_t *dst, vlib_buffer_free_list_t *fl)
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
static vlib_buffer_known_state_t vlib_buffer_is_known(u32 buffer_index)
vlib_buffer_main_t buffer_main
static uword clib_mem_is_vec(void *v)
Predicate function, says whether the supplied vector is a clib heap object.
static void vlib_buffer_set_free_list_index(vlib_buffer_t *b, vlib_buffer_free_list_index_t index)
static_always_inline vlib_buffer_pool_t * vlib_buffer_pool_get(u8 buffer_pool_index)
static void * vlib_physmem_alloc_from_map(vlib_main_t *vm, u32 physmem_map_index, uword n_bytes, uword alignment)
u8 vlib_buffer_free_list_index_t
static vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, vlib_buffer_free_list_index_t free_list_index)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
static void del_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
u32 trace_index
Specifies index into trace buffer if VLIB_PACKET_IS_TRACED flag is set.
uword * free_list_by_size
#define clib_panic(format, args...)
void vlib_buffer_validate_alloc_free(vlib_main_t *vm, u32 *buffers, uword n_buffers, vlib_buffer_known_state_t expected_state)
#define vlib_panic_with_msg(vm, args...)
vlib_buffer_free_list_index_t vlib_buffer_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
static uword vlib_buffer_fill_free_list_internal(vlib_main_t *vm, vlib_buffer_free_list_t *fl, uword min_free_buffers)
static void vlib_buffer_free_internal(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
static u32 vlib_buffer_round_size(u32 size)
static uword pool_elts(void *v)
Number of active elements in a pool.