71 s =
format (s,
"current data %d, length %d, free-list %d",
96 format_vlib_buffer_known_state (
u8 * s, va_list * args)
98 vlib_buffer_known_state_t state = va_arg (*args, vlib_buffer_known_state_t);
103 case VLIB_BUFFER_UNKNOWN:
107 case VLIB_BUFFER_KNOWN_ALLOCATED:
108 t =
"known-allocated";
111 case VLIB_BUFFER_KNOWN_FREE:
120 return format (s,
"%s", t);
143 uword follow_buffer_next,
uword ** unique_hash)
158 return format (0,
"%d-%d beyond end of buffer %d",
164 vlib_buffer_known_state_t k;
168 if (k != VLIB_BUFFER_KNOWN_ALLOCATED)
169 return format (0,
"next 0x%x: %U",
170 b->
next_buffer, format_vlib_buffer_known_state, k);
180 msg = vlib_validate_buffer (vm, b->
next_buffer, follow_buffer_next);
195 return vlib_validate_buffer_helper (vm, bi, follow_buffer_next,
202 uword next_buffer_stride,
204 vlib_buffer_known_state_t known_state,
205 uword follow_buffer_next)
208 u32 bi, *b = buffers;
209 vlib_buffer_known_state_t k;
210 u8 *msg = 0, *result = 0;
213 for (i = 0; i < n_buffers; i++)
216 b += next_buffer_stride;
221 msg =
format (0,
"not unique");
225 k = vlib_buffer_is_known (vm, bi);
226 if (k != known_state)
228 msg =
format (0,
"is %U; expected %U",
229 format_vlib_buffer_known_state, k,
230 format_vlib_buffer_known_state, known_state);
234 msg = vlib_validate_buffer_helper (vm, bi, follow_buffer_next, &hash);
244 result =
format (0,
"0x%x: %v", bi, msg);
259 vlib_buffer_known_state_t expected_state)
271 ASSERT (vm == vlib_mains[0]);
273 is_free = expected_state == VLIB_BUFFER_KNOWN_ALLOCATED;
275 for (i = 0; i < n_buffers; i++)
277 vlib_buffer_known_state_t known;
281 known = vlib_buffer_is_known (vm, bi);
282 if (known != expected_state)
286 (vm,
"%s %U buffer 0x%x",
287 is_free ?
"freeing" :
"allocating",
288 format_vlib_buffer_known_state, known, bi);
291 vlib_buffer_set_known_state
293 is_free ? VLIB_BUFFER_KNOWN_FREE : VLIB_BUFFER_KNOWN_ALLOCATED);
307 ASSERT (n_bytes %
sizeof (dst[0]) == 0);
314 while (n_bytes >= 4 *
sizeof (dst[0]))
318 n_bytes -= 4 *
sizeof (dst[0]);
332 while (n_bytes >= 8 *
sizeof (dst[0]))
336 n_bytes -= 8 *
sizeof (dst[0]);
355 n_bytes -= 1 *
sizeof (dst[0]);
359 #define BUFFERS_PER_COPY (sizeof (vlib_copy_unit_t) / sizeof (u32)) 365 uword n_unaligned_buffers)
371 ASSERT (la % BUFFERS_PER_COPY == 0);
373 ASSERT (la >= n_unaligned_buffers);
375 while (lu < n_unaligned_buffers)
450 return p ? p[0] : ~0;
457 u32 is_public,
u32 is_default,
u8 * name)
464 u32 default_free_free_list_index;
476 ASSERT (default_free_free_list_index ==
480 return default_free_free_list_index;
485 memset (f, 0,
sizeof (f[0]));
571 if (merge_index != ~0 && merge_index != free_list_index)
580 memset (f, 0xab,
sizeof (f[0]));
593 u32 n_remaining, n_alloc, n_this_chunk;
600 return min_free_buffers;
610 while (n_remaining > 0)
612 n_this_chunk =
clib_min (n_remaining, 16);
614 n_bytes = n_this_chunk * (
sizeof (b[0]) + fl->
n_data_bytes);
627 n_alloc += n_this_chunk;
628 n_remaining -= n_this_chunk;
633 for (i = 0; i < n_this_chunk; i++)
638 vlib_buffer_set_known_state (vm, bi[i], VLIB_BUFFER_KNOWN_FREE);
642 memset (buffers, 0, n_bytes);
646 for (i = 0; i < n_this_chunk; i++)
667 u32 * alloc_buffers,
u32 n_alloc_buffers)
671 uword n_unaligned_start, n_unaligned_end, n_filled;
675 n_left = n_alloc_buffers;
678 & (BUFFERS_PER_COPY - 1));
684 n_left = n_filled < n_left ? n_filled : n_left;
685 n_alloc_buffers = n_left;
687 if (n_unaligned_start >= n_left)
689 n_unaligned_start = n_left;
695 fill_unaligned (vm, free_list, n_unaligned_start + n_unaligned_end);
700 if (n_unaligned_start)
702 uword n_copy = n_unaligned_start;
725 ((n_left / BUFFERS_PER_COPY) * BUFFERS_PER_COPY))
761 ASSERT (n_unaligned_end == n_left);
775 vlib_buffer_validate_alloc_free (vm, alloc_buffers,
776 n_alloc_buffers, VLIB_BUFFER_KNOWN_FREE);
778 return n_alloc_buffers;
800 u32 n_buffers,
u32 free_list_index)
811 u32 buffer_index,
u8 do_init)
841 void vnet_buffer_free_dpdk_mb (
vlib_buffer_t * b) __attribute__ ((weak));
849 u32 * buffers,
u32 n_buffers,
u32 follow_buffer_next)
853 static u32 *next_to_free[2];
854 u32 i_next_to_free, *b, *n, *f, fi;
859 u32 bi0 = (
u32) ~ 0, bi1 = (
u32) ~ 0, fi0, fi1 = (
u32) ~ 0;
860 u8 free0, free1 = 0, free_next0, free_next1;
862 u32 follow_buffer_next);
869 n_buffers = (*cb) (vm, buffers, n_buffers, follow_buffer_next);
876 u32 bi0 = buffers[0];
894 vlib_buffer_validate_alloc_free (vm, b,
895 n_left, VLIB_BUFFER_KNOWN_ALLOCATED);
900 n = next_to_free[i_next_to_free];
925 if (follow_buffer_next)
936 free_next0 = free_next1 = 0;
945 binit0 = free0 ? b0 : &dummy_buffers[0];
946 binit1 = free1 ? b1 : &dummy_buffers[1];
954 n -= free_next0 + free_next1;
965 for (i = 0; i <
vec_len (announce_list); i++)
966 if (fl0 == announce_list[i])
971 if (
PREDICT_FALSE (fl1->buffers_added_to_freelist_function != 0))
974 for (i = 0; i <
vec_len (announce_list); i++)
975 if (fl1 == announce_list[i])
984 if (fi0 != fi && fi1 != fi)
1009 if (follow_buffer_next)
1024 binit0 = free0 ? b0 : &dummy_buffers[0];
1042 for (i = 0; i <
vec_len (announce_list); i++)
1043 if (fl0 == announce_list[i])
1056 if (follow_buffer_next && ((n_left = n - next_to_free[i_next_to_free]) > 0))
1058 b = next_to_free[i_next_to_free];
1059 i_next_to_free ^= 1;
1068 for (i = 0; i <
vec_len (announce_list); i++)
1070 fl = announce_list[
i];
1073 _vec_len (announce_list) = 0;
1095 u32 * buffers,
u32 n_buffers)
1102 for (i = 0; i < n_buffers; i++)
1115 uword n_packet_data_bytes,
1116 uword min_n_buffers_each_physmem_alloc,
1127 memset (t, 0,
sizeof (t[0]));
1133 (vm, n_packet_data_bytes,
1190 u32 free_list_index,
1191 u32 buffer_index,
void *data,
u32 n_data_bytes)
1193 u32 n_buffer_bytes, n_left, n_left_this_buffer, bi;
1200 goto out_of_buffers;
1203 n_left = n_data_bytes;
1218 n_left_this_buffer =
1220 n =
clib_min (n_left_this_buffer, n_left);
1231 goto out_of_buffers;
1247 u32 free_list_index,
1250 void *data,
u16 data_len)
1253 u32 n_buffer_bytes =
1270 u16 len = (data_len > max) ? max : data_len;
1272 data + copied, len);
1294 uword n, n_bytes_to_write;
1303 ASSERT (sm->
tx.max_n_data_bytes_per_chain > 0);
1305 || sm->
tx.n_total_data_bytes + n_bytes_to_write >
1306 sm->
tx.max_n_data_bytes_per_chain)
1317 sm->
tx.n_total_data_bytes = 0;
1326 sm->
tx.free_list_index);
1330 (
"vlib_buffer_alloc_from_free_list fails"));
1336 if (n_bytes_to_write > 0)
1341 sm->
tx.free_list_index);
1345 (
"vlib_buffer_alloc_from_free_list fails"));
1346 sm->
tx.n_total_data_bytes += n_bytes_to_write;
1393 sm->
rx.ready_one_time_event =
1397 sm->
rx.ready_one_time_event);
1420 memset (m, 0,
sizeof (m[0]));
1423 _vec_len (save) = 0;
1430 sm->
tx.n_total_data_bytes = 0;
1492 uword bytes_alloc, bytes_free, n_free,
size;
1495 return format (s,
"%=30s%=12s%=12s%=12s%=12s%=12s%=12s",
1496 "Name",
"Index",
"Size",
"Alloc",
"Free",
"#Alloc",
1501 bytes_alloc = size * f->
n_alloc;
1502 bytes_free = size * n_free;
1504 s =
format (s,
"%30s%12d%12d%=12U%=12U%=12d%=12d",
1522 vlib_cli_output (vm,
"%U", format_vlib_buffer_free_list, f);
1531 .path =
"show buffers",
1532 .short_help =
"Show packet buffer allocation",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
#define hash_set(h, key, value)
sll srl srl sll sra u16x4 i
u32 vlib_buffer_get_or_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
uword vlib_buffer_length_in_chain_slow_path(vlib_main_t *vm, vlib_buffer_t *b_first)
vlib_node_runtime_t node_runtime
static uword clib_fifo_elts(void *v)
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
static uword vlib_current_process(vlib_main_t *vm)
format_function_t format_vlib_buffer_contents
u32 free_list_index
Buffer free list that this buffer was allocated from and will be freed to.
vlib_physmem_main_t physmem_main
format_function_t format_vlib_buffer
serialize_main_header_t header
static void serialize_error(serialize_main_header_t *m, clib_error_t *error)
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.
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
struct vlib_serialize_buffer_main_t::@22::@24 tx
struct vlib_main_t * vlib_main
#define clib_error(format, args...)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static void fill_unaligned(vlib_main_t *vm, vlib_buffer_free_list_t *free_list, uword n_unaligned_buffers)
static heap_elt_t * last(heap_header_t *h)
u32 serialize_close_vlib_buffer(serialize_main_t *m)
void ** buffer_memory_allocated
vlib_buffer_main_t * buffer_main
static u32 vlib_buffer_create_free_list_helper(vlib_main_t *vm, u32 n_data_bytes, u32 is_public, u32 is_default, u8 *name)
u32 min_n_buffers_each_physmem_alloc
static_always_inline void vlib_buffer_free_inline(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
void * vlib_set_buffer_free_callback(struct vlib_main_t *vm, void *fp)
struct vlib_serialize_buffer_main_t::@22::@25 rx
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
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,...)
#define vec_add1_aligned(V, E, A)
Add 1 element to end of vector (alignment specified).
static void vlib_buffer_init_for_free_list(vlib_buffer_t *_dst, 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)
Iterate through pool.
void(* buffer_init_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
#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...
void unserialize_close_vlib_buffer(serialize_main_t *m)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static void vlib_buffer_init_two_for_free_list(vlib_buffer_t *_dst0, vlib_buffer_t *_dst1, vlib_buffer_free_list_t *fl)
static uword serialize_stream_is_end_of_stream(serialize_stream_t *s)
static void trim_aligned(vlib_buffer_free_list_t *f)
void vlib_aligned_memcpy(void *_dst, void *_src, int n_bytes)
#define vec_end(v)
End (last data address) of vector.
static uword pointer_to_uword(const void *p)
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
#define VLIB_BUFFER_NEXT_PRESENT
vlib_main_t ** vlib_mains
#define VLIB_BUFFER_PRE_DATA_SIZE
static void vlib_packet_template_buffer_init(vlib_main_t *vm, vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void vlib_serialize_rx(serialize_main_header_t *m, serialize_stream_t *s)
#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.
format_function_t format_vlib_buffer_and_data
static clib_error_t * show_buffers(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
uword os_get_cpu_number(void)
#define pool_put(P, E)
Free an object E in pool P.
void serialize_open_vlib_buffer(serialize_main_t *m, struct vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
#define clib_error_create(args...)
static u32 vlib_buffer_free_list_buffer_size(vlib_main_t *vm, u32 free_list_index)
static void clib_fifo_reset(void *v)
static vlib_buffer_free_list_t * buffer_get_free_list(vlib_main_t *vm, vlib_buffer_t *b, u32 *index)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static void vlib_serialize_tx(serialize_main_header_t *m, serialize_stream_t *s)
static uword copy_alignment(u32 *x)
#define uword_to_pointer(u, type)
#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)
serialize_stream_t stream
static vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
u32(* buffer_free_callback)(struct vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
#define CLIB_PREFETCH(addr, size, type)
void *(* os_physmem_alloc_aligned)(vlib_physmem_main_t *pm, uword n_bytes, uword alignment)
static uword vlib_process_wait_for_one_time_event(vlib_main_t *vm, uword **data_vector, uword with_type_index)
void vlib_buffer_chain_validate(vlib_main_t *vm, vlib_buffer_t *first)
#define vec_free(V)
Free vector's memory (no header).
#define clib_memcpy(a, b, c)
static uword vlib_process_create_one_time_event(vlib_main_t *vm, uword node_index, uword with_type_opaque)
serialize_data_function_t * data_function
#define VLIB_BUFFER_RECYCLE
#define VLIB_BUFFER_TOTAL_LENGTH_VALID
void(* buffers_added_to_freelist_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
static void add_buffer_to_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f, u32 buffer_index, u8 do_init)
static u8 * format_vlib_buffer_free_list(u8 *s, va_list *va)
static uword round_pow2(uword x, uword pow2)
uword data_function_opaque
#define hash_set1(h, key)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
#define hash_create(elts, value_bytes)
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
static u32 alloc_from_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *free_list, u32 *alloc_buffers, u32 n_alloc_buffers)
u32 next_buffer
Next buffer for this linked-list of buffers.
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)
void unserialize_open_vlib_buffer(serialize_main_t *m, struct vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
u32 vlib_buffer_add_data(vlib_main_t *vm, u32 free_list_index, u32 buffer_index, void *data, u32 n_data_bytes)
static uword clib_mem_is_heap_object(void *p)
static uword fill_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *fl, uword min_free_buffers)
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
void(* os_physmem_free)(void *x)
#define VLIB_BUFFER_IS_TRACED
void vlib_buffer_delete_free_list(vlib_main_t *vm, u32 free_list_index)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
static u32 vlib_buffer_get_free_list_with_size(vlib_main_t *vm, u32 size)
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
static vlib_buffer_t * vlib_buffer_next_contiguous(vlib_buffer_t *b, u32 buffer_bytes)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void del_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f)
vlib_buffer_free_list_t * buffer_free_list_pool
void * vlib_packet_template_get_packet(vlib_main_t *vm, vlib_packet_template_t *t, u32 *bi_result)
uword buffer_init_function_opaque
static void vlib_buffer_free_one(vlib_main_t *vm, u32 buffer_index)
Free one buffer Shorthand to free a single buffer chain.
void vlib_packet_template_get_packet_helper(vlib_main_t *vm, vlib_packet_template_t *t)
static vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, u32 free_list_index)
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.
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
u32 min_n_buffers_each_physmem_alloc
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
u32 vlib_buffer_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
#define vlib_panic_with_msg(vm, args...)
static void merge_free_lists(vlib_buffer_free_list_t *dst, vlib_buffer_free_list_t *src)
static u32 vlib_buffer_round_size(u32 size)
static void serialize_open_vlib_helper(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm, uword is_read)
static uword pool_elts(void *v)
Number of active elements in a pool.