40 #include <rte_config.h> 42 #include <rte_common.h> 44 #include <rte_memory.h> 45 #include <rte_memzone.h> 46 #include <rte_tailq.h> 48 #include <rte_per_lcore.h> 49 #include <rte_launch.h> 50 #include <rte_atomic.h> 51 #include <rte_cycles.h> 52 #include <rte_prefetch.h> 53 #include <rte_lcore.h> 54 #include <rte_per_lcore.h> 55 #include <rte_branch_prediction.h> 56 #include <rte_interrupts.h> 58 #include <rte_random.h> 59 #include <rte_debug.h> 60 #include <rte_ether.h> 61 #include <rte_ethdev.h> 63 #include <rte_mempool.h> 68 #pragma weak rte_mem_virt2phy 69 #pragma weak rte_eal_has_hugepages 70 #pragma weak rte_socket_id 71 #pragma weak rte_pktmbuf_pool_create 93 s =
format (s,
"current data %d, length %d, free-list %d",
98 s =
format (s,
", totlen-nifb %d",
110 s =
format (s,
"\n%Unext-buffer 0x%x, segment length %d",
158 ASSERT (n_bytes %
sizeof (dst[0]) == 0);
165 while (n_bytes >= 4 *
sizeof (dst[0]))
169 n_bytes -= 4 *
sizeof (dst[0]);
183 while (n_bytes >= 8 *
sizeof (dst[0]))
187 n_bytes -= 8 *
sizeof (dst[0]);
206 n_bytes -= 1 *
sizeof (dst[0]);
210 #define BUFFERS_PER_COPY (sizeof (vlib_copy_unit_t) / sizeof (u32)) 216 uword n_unaligned_buffers)
224 ASSERT (la >= n_unaligned_buffers);
226 while (lu < n_unaligned_buffers)
301 return p ? p[0] : ~0;
317 u32 default_free_free_list_index;
319 default_free_free_list_index =
328 return default_free_free_list_index;
333 memset (f, 0,
sizeof (f[0]));
400 mb = rte_mbuf_from_vlib_buffer(b);
401 ASSERT(rte_mbuf_refcnt_read(mb) == 1);
402 rte_pktmbuf_free (mb);
406 mb = rte_mbuf_from_vlib_buffer(b);
407 ASSERT(rte_mbuf_refcnt_read(mb) == 1);
408 rte_pktmbuf_free (mb);
425 if (merge_index != ~0 && merge_index != free_list_index)
434 memset (f, 0xab,
sizeof (f[0]));
443 uword min_free_buffers)
448 u32 n_remaining = 0, n_alloc = 0;
449 unsigned socket_id = rte_socket_id ? rte_socket_id() : 0;
450 struct rte_mempool *rmp = vm->
buffer_main->pktmbuf_pools[socket_id];
462 return min_free_buffers;
477 for (i = 0; i < n; i++)
481 ASSERT(rte_mbuf_refcnt_read(mb) == 0);
482 rte_mbuf_refcnt_set(mb, 1);
484 mb->data_off = RTE_PKTMBUF_HEADROOM;
487 b = vlib_buffer_from_rte_mbuf(mb);
517 uword n_unaligned_start, n_unaligned_end, n_filled;
519 n_left = n_alloc_buffers;
528 n_left = n_filled < n_left ? n_filled : n_left;
529 n_alloc_buffers = n_left;
531 if (n_unaligned_start >= n_left)
533 n_unaligned_start = n_left;
539 fill_unaligned (vm, free_list, n_unaligned_start + n_unaligned_end);
544 if (n_unaligned_start)
546 uword n_copy = n_unaligned_start;
604 ASSERT (n_unaligned_end == n_left);
617 return n_alloc_buffers;
648 u32 buffer_index,
u8 do_init)
680 u32 follow_buffer_next)
687 u32 follow_buffer_next);
692 n_buffers = (*cb)(vm, buffers, n_buffers, follow_buffer_next);
697 for (i = 0; i < n_buffers; i++)
700 struct rte_mbuf * mb;
716 goto already_announced;
726 mb = rte_mbuf_from_vlib_buffer(b);
727 ASSERT(rte_mbuf_refcnt_read(mb) == 1);
728 rte_pktmbuf_free (mb);
759 __attribute__((unused))
static void 769 for (i = 0; i < n_buffers; i++)
780 uword n_packet_data_bytes,
781 uword min_n_buffers_each_physmem_alloc,
786 __attribute__((unused))
u8 * name;
793 memset (t, 0,
sizeof (t[0]));
819 struct rte_mbuf * mb;
820 mb = rte_mbuf_from_vlib_buffer(b);
831 void * data,
u32 n_data_bytes)
833 u32 n_buffer_bytes, n_left, n_left_this_buffer, bi;
843 n_left = n_data_bytes;
859 n =
clib_min (n_left_this_buffer, n_left);
887 void * data,
u16 data_len) {
901 u16 len = (data_len > max)?max:data_len;
916 struct rte_mbuf *mb_prev, *mb, *mb_first;
918 mb_first = rte_mbuf_from_vlib_buffer(b_first);
923 mb = rte_mbuf_from_vlib_buffer(b);
924 mb_prev = rte_mbuf_from_vlib_buffer(prev);
939 struct rte_mempool * rmp;
940 uword new_start, new_size;
943 if (!rte_pktmbuf_pool_create)
949 if (bm->pktmbuf_pools[socket_id])
952 u8 * pool_name =
format(0,
"mbuf_pool_socket%u%c",socket_id, 0);
954 rmp = rte_pktmbuf_pool_create((
char *) pool_name,
967 new_size = rmp->elt_va_end - new_start;
972 if (new_start < vpm->
virtual.start)
990 bm->pktmbuf_pools[socket_id] = rmp;
998 for (i = 0; i <
vec_len(bm->pktmbuf_pools); i++)
1000 if(bm->pktmbuf_pools[i])
1002 clib_warning(
"WARNING: Failed to allocate mempool for CPU socket %u. " 1003 "Threads running on socket %u will use socket %u mempool.",
1004 socket_id, socket_id, i);
1005 bm->pktmbuf_pools[socket_id] = bm->pktmbuf_pools[
i];
1019 uword n, n_bytes_to_write;
1026 ASSERT (sm->
tx.max_n_data_bytes_per_chain > 0);
1028 || sm->
tx.n_total_data_bytes + n_bytes_to_write > sm->
tx.max_n_data_bytes_per_chain)
1038 sm->
tx.n_total_data_bytes = 0;
1052 if (n_bytes_to_write > 0)
1058 sm->
tx.n_total_data_bytes += n_bytes_to_write;
1127 memset (m, 0,
sizeof (m[0]));
1130 _vec_len (save) = 0;
1137 sm->
tx.n_total_data_bytes = 0;
1186 u32 threadnum= va_arg (*va,
u32);
1187 uword bytes_alloc, bytes_free, n_free,
size;
1190 return format (s,
"%=7s%=30s%=12s%=12s%=12s%=12s%=12s%=12s",
1191 "Thread",
"Name",
"Index",
"Size",
"Alloc",
"Free",
"#Alloc",
"#Free");
1195 bytes_alloc = size * f->
n_alloc;
1196 bytes_free = size * n_free;
1198 s =
format (s,
"%7d%30s%12d%12d%=12U%=12U%=12d%=12d",
1221 curr_vm =
vec_len(vlib_mains) ? vlib_mains[vm_index] : vm;
1225 vlib_cli_output (vm,
"%U", format_vlib_buffer_free_list, f, vm_index);
1229 }
while (vm_index <
vec_len(vlib_mains));
1235 .path =
"show buffers",
1236 .short_help =
"Show packet buffer allocation",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void vlib_buffer_chain_validate(vlib_main_t *vm, vlib_buffer_t *b_first)
uword * vlib_buffer_state_validation_hash
always_inline uword round_pow2(uword x, uword pow2)
#define hash_set(h, key, value)
sll srl srl sll sra u16x4 i
always_inline uword vlib_process_create_one_time_event(vlib_main_t *vm, uword node_index, uword with_type_opaque)
vlib_node_runtime_t node_runtime
u32 free_list_index
Buffer free list that this buffer was allocated from and will be freed to.
vlib_physmem_main_t physmem_main
void * mheap_alloc(void *memory, uword size)
void * vlib_buffer_state_heap
serialize_main_header_t header
#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
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_error(format, args...)
#define CLIB_LOG2_CACHE_LINE_BYTES
#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)
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)
always_inline uword copy_alignment(u32 *x)
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
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
static_always_inline void vlib_buffer_free_inline(vlib_main_t *vm, u32 *buffers, u32 n_buffers, u32 follow_buffer_next)
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)
always_inline vlib_main_t * vlib_get_main(void)
struct vlib_serialize_buffer_main_t::@27::@30 rx
#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
void unserialize_open_vlib_buffer(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
#define pool_foreach(VAR, POOL, BODY)
always_inline heap_elt_t * last(heap_header_t *h)
#define VLIB_INIT_FUNCTION(x)
static void trim_aligned(vlib_buffer_free_list_t *f)
always_inline uword pool_elts(void *v)
always_inline uword clib_fifo_elts(void *v)
#define clib_warning(format, args...)
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.
void serialize_open_vlib_buffer(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm)
u8 * format_vlib_buffer_contents(u8 *s, va_list *va)
u8 * format_vlib_buffer(u8 *s, va_list *args)
static uword pointer_to_uword(const void *p)
#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)
vlib_buffer_free_list_t ** announce_list
always_inline u32 vlib_buffer_get_free_list_with_size(vlib_main_t *vm, u32 size)
vlib_main_t ** vlib_mains
#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)
static void vlib_serialize_rx(serialize_main_header_t *m, serialize_stream_t *s)
uword vlib_buffer_length_in_chain_slow_path(vlib_main_t *vm, vlib_buffer_t *b_first)
always_inline void clib_fifo_reset(void *v)
#define clib_fifo_sub1(f, e)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES
u32 serialize_close_vlib_buffer(serialize_main_t *m)
u16 current_length
Nbytes between current data and the end of this buffer.
void vlib_aligned_memcpy(void *_dst, void *_src, int n_bytes)
static clib_error_t * show_buffers(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
always_inline uword vlib_process_wait_for_one_time_event(vlib_main_t *vm, uword **data_vector, uword with_type_index)
#define clib_error_create(args...)
always_inline void * clib_mem_set_heap(void *heap)
u32 vlib_buffer_get_or_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static void vlib_serialize_tx(serialize_main_header_t *m, serialize_stream_t *s)
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)
clib_error_t * vlib_buffer_pool_create(vlib_main_t *vm, unsigned num_mbufs, unsigned socket_id)
#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)
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)
u8 * format_vlib_buffer_and_data(u8 *s, va_list *args)
#define vec_free(V)
Free vector's memory (no header).
always_inline void add_buffer_to_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *f, u32 buffer_index, u8 do_init)
void vlib_buffer_delete_free_list(vlib_main_t *vm, u32 free_list_index)
void unserialize_close_vlib_buffer(serialize_main_t *m)
#define clib_memcpy(a, b, c)
u32 * vlib_buffer_state_validation_lock
serialize_data_function_t * data_function
#define VLIB_BUFFER_TOTAL_LENGTH_VALID
static u8 * format_vlib_buffer_free_list(u8 *s, va_list *va)
uword data_function_opaque
#define VLIB_CLI_COMMAND(x,...)
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
#define hash_create(elts, value_bytes)
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
#define VLIB_BUFFER_HDR_SIZE
static u32 alloc_from_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *free_list, u32 *alloc_buffers, u32 n_alloc_buffers)
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 next_buffer
Next buffer for this linked-list of buffers.
u32 clone_count
Specifies whether this buffer should be reinitialized when freed.
static uword fill_free_list(vlib_main_t *vm, vlib_buffer_free_list_t *fl, uword min_free_buffers)
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
#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.
always_inline vlib_buffer_free_list_t * buffer_get_free_list(vlib_main_t *vm, vlib_buffer_t *b, u32 *index)
always_inline uword clib_mem_is_heap_object(void *p)
#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)
void(* buffer_init_function)(struct vlib_main_t *vm, struct vlib_buffer_free_list_t *fl, u32 *buffers, u32 n_buffers)
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.
vlib_buffer_free_list_t * buffer_free_list_pool
always_inline void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
#define VLIB_BUFFER_DATA_SIZE
void * vlib_set_buffer_free_callback(vlib_main_t *vm, void *fp)
always_inline uword vlib_current_process(vlib_main_t *vm)
vlib_physmem_region_t virtual
always_inline vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
void * vlib_packet_template_get_packet(vlib_main_t *vm, vlib_packet_template_t *t, u32 *bi_result)
always_inline u32 vlib_buffer_round_size(u32 size)
u32 vlib_buffer_add_data(vlib_main_t *vm, u32 free_list_index, u32 buffer_index, void *data, u32 n_data_bytes)
uword buffer_init_function_opaque
#define clib_error_return(e, args...)
#define CLIB_CACHE_LINE_BYTES
static clib_error_t * buffer_state_validation_init(vlib_main_t *vm)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
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
static void merge_free_lists(vlib_buffer_free_list_t *dst, vlib_buffer_free_list_t *src)
struct vlib_serialize_buffer_main_t::@27::@29 tx
u32 vlib_buffer_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
static void serialize_open_vlib_helper(serialize_main_t *m, vlib_main_t *vm, vlib_serialize_buffer_main_t *sm, uword is_read)