61 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
67 b_first->
flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
78 #define _(bit, name, v) \ 79 if (v && (b->flags & VLIB_BUFFER_##name)) \ 80 a = format (a, "%s ", v); 83 s =
format (s,
"current data %d, length %d, free-list %d, clone-count %u",
87 if (b->
flags & VLIB_BUFFER_TOTAL_LENGTH_VALID)
88 s =
format (s,
", totlen-nifb %d",
91 if (b->
flags & VLIB_BUFFER_IS_TRACED)
98 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
105 format (s,
"\n%Unext-buffer 0x%x, segment length %d, clone-count %u",
138 t =
"known-allocated";
150 return format (s,
"%s", t);
162 if (!(b->
flags & VLIB_BUFFER_NEXT_PRESENT))
173 uword follow_buffer_next,
uword ** unique_hash)
180 return format (0,
"unknown free list 0x%x",
191 return format (0,
"%d-%d beyond end of buffer %d",
194 if (follow_buffer_next && (b->
flags & VLIB_BUFFER_NEXT_PRESENT))
201 return format (0,
"next 0x%x: %U",
234 uword next_buffer_stride,
237 uword follow_buffer_next)
240 u32 bi, *b = buffers;
242 u8 *msg = 0, *result = 0;
245 for (i = 0; i < n_buffers; i++)
248 b += next_buffer_stride;
253 msg =
format (0,
"not unique");
258 if (k != known_state)
260 msg =
format (0,
"is %U; expected %U",
276 result =
format (0,
"0x%x: %v", bi, msg);
295 } __attribute__ ((packed)) __bootstrap_vlib_main_vector
320 if (vlib_buffer_callbacks)
325 for (i = 0; i < n_buffers; i++)
332 if (known != expected_state)
336 (vm,
"%s %U buffer 0x%x",
337 is_free ?
"freeing" :
"allocating",
350 u32 is_public,
u32 is_default,
u8 * name)
363 default_free_free_list_index =
371 ASSERT (default_free_free_list_index ==
375 return default_free_free_list_index;
380 memset (f, 0,
sizeof (f[0]));
398 for (i = 1; i <
vec_len (vlib_mains); i++)
442 memset (f, 0xab,
sizeof (f[0]));
463 for (i = 1; i <
vec_len (vlib_mains); i++)
499 uword min_free_buffers)
510 return min_free_buffers;
520 _vec_len (bp->
buffers) = n_left;
524 return min_free_buffers;
585 (b->
flags & VLIB_BUFFER_RECYCLE) == 0);
589 goto already_announced;
616 while (follow_buffer_next && (flags & VLIB_BUFFER_NEXT_PRESENT));
624 u32 * buffers,
u32 n_buffers,
u32 follow_buffer_next)
630 u32 follow_buffer_next);
635 n_buffers = (*cb) (
vm, buffers, n_buffers, follow_buffer_next);
640 while (i + 11 < n_buffers)
669 while (i < n_buffers)
705 static void __attribute__ ((unused))
708 u32 * buffers,
u32 n_buffers)
715 for (i = 0; i < n_buffers; i++)
728 uword n_packet_data_bytes,
729 uword min_n_buffers_each_alloc,
char *fmt, ...)
743 min_n_buffers_each_alloc, name);
747 memset (t, 0,
sizeof (t[0]));
753 (vm, n_packet_data_bytes,
813 u32 buffer_index,
void *data,
u32 n_data_bytes)
815 u32 n_buffer_bytes, n_left, n_left_this_buffer, bi;
825 n_left = n_data_bytes;
829 b->
flags &= ~VLIB_BUFFER_TOTAL_LENGTH_VALID;
832 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
842 n =
clib_min (n_left_this_buffer, n_left);
855 b->
flags |= VLIB_BUFFER_NEXT_PRESENT;
893 u16 len = (data_len > max) ? max : data_len;
918 else if (start < bm->buffer_mem_start)
935 clib_panic (
"buffer memory size out of range!");
943 if (buffer_size == 0)
961 u32 threadnum = va_arg (*va,
u32);
962 uword bytes_alloc, bytes_free, n_free,
size;
965 return format (s,
"%=7s%=30s%=12s%=12s%=12s%=12s%=12s%=12s",
966 "Thread",
"Name",
"Index",
"Size",
"Alloc",
"Free",
971 bytes_alloc = size * f->
n_alloc;
972 bytes_free = size * n_free;
974 s =
format (s,
"%7d%30v%12d%12d%=12U%=12U%=12d%=12d", threadnum,
998 vlib_cli_output (vm,
"%U", format_vlib_buffer_free_list, f, vm_index);
1011 .path =
"show buffers",
1012 .short_help =
"Show packet buffer allocation",
1024 if (vlib_buffer_callbacks)
1069 if (
unformat (input,
"memory-size-in-mb %d", &size_in_mb))
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
vlib_physmem_region_index_t physmem_region
vlib_main_t vlib_global_main
u32 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)
#define hash_set(h, key, value)
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
#define VLIB_PHYSMEM_F_HUGETLB
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)
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)
#define clib_error(format, args...)
vlib_buffer_callbacks_t cb
static vlib_buffer_t * vlib_buffer_chain_buffer(vlib_main_t *vm, vlib_buffer_t *first, vlib_buffer_t *last, u32 next_bi)
#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
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static clib_error_t * vlib_physmem_region_alloc(vlib_main_t *vm, char *name, u32 size, u8 numa_node, u32 flags, vlib_physmem_region_index_t *idx)
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 uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
static void vlib_buffer_free_no_next_internal(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
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
vlib_main_t ** vlib_mains
uword vlib_buffer_length_in_chain_slow_path(vlib_main_t *vm, vlib_buffer_t *b_first)
vlib_buffer_free_list_index_t free_list_index
void vlib_packet_template_get_packet_helper(vlib_main_t *vm, vlib_packet_template_t *t)
#define vlib_worker_thread_barrier_sync(X)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
#define VLIB_PHYSMEM_F_SHARED
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)
u8 vlib_buffer_pool_create(vlib_main_t *vm, vlib_physmem_region_index_t pri, u16 buffer_size)
#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 vlib_physmem_region_t * vlib_physmem_get_region(vlib_main_t *vm, u8 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)
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.
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)
static_always_inline void * vlib_buffer_pool_get_buffer(vlib_buffer_pool_t *bp)
vlib_buffer_free_list_t * buffer_free_list_pool
static void vlib_packet_template_buffer_init(vlib_main_t *vm, vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
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 (general version).
#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_memcpy(a, b, c)
void(* buffers_added_to_freelist_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl)
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)
#define uword_to_pointer(u, type)
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)
void(* vlib_packet_template_init_cb)(struct vlib_main_t *vm, void *t, void *packet_data, uword n_packet_data_bytes, uword min_n_buffers_each_physmem_alloc, u8 *name)
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.
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)
#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)
u8 vlib_buffer_free_list_index_t
uword buffer_init_function_opaque
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.
u8 vlib_physmem_region_index_t
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)
vlib_buffer_free_list_t ** buffer_announce_list
#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.