|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
22 uword cur_pos, cur_pos_align, new_pos;
27 new_pos = cur_pos_align +
size;
36 new_pos = cur_pos_align +
size;
52 return &fsh->
slices[slice_index];
58 ASSERT (slice_index < fs->n_slices);
59 return &fs->
slices[slice_index];
63 #define _(sym,str) str,
137 #define FS_CL_HEAD_MASK 0xFFFFFFFFFFFF
138 #define FS_CL_HEAD_TMASK 0xFFFF000000000000
139 #define FS_CL_HEAD_TINC (1ULL << 48)
165 while (!__atomic_compare_exchange (&fss->
free_chunks[fl_index], &old_head,
166 &new_head, 0 , __ATOMIC_RELEASE,
186 while (!__atomic_compare_exchange (&fss->
free_chunks[fl_index], &old_head,
187 &new_head, 0 , __ATOMIC_RELEASE,
216 while (!__atomic_compare_exchange (&fss->
free_chunks[fl_index], &old_head,
217 &new_head, 0 , __ATOMIC_RELEASE,
266 f->prev->next =
f->next;
270 f->next->prev =
f->prev;
298 u32 align = 8,
offset = 2 * 4096, slices_sz,
i;
299 uword max_fifo, seg_start, seg_sz;
316 memset (fsh, 0,
sizeof (*fsh) + slices_sz);
458 u32 timeout_in_seconds)
494 u32 fl_index, fl_size, n_alloc = 0, req_bytes = data_bytes;
511 req_bytes -=
clib_min (fl_size, req_bytes);
544 fl_size = fl_size >> 1;
573 for (
i = 0;
i < batch_size;
i++)
590 u32 fl_index,
u32 batch_size)
594 u32 rounded_data_size;
601 total_chunk_bytes = (
uword) batch_size *rounded_data_size;
602 size = (
uword) (
sizeof (*
c) + rounded_data_size) * batch_size;
610 for (
i = 0;
i < batch_size;
i++)
613 c->length = rounded_data_size;
616 cmem +=
sizeof (*c) + rounded_data_size;
631 u32 fl_index,
u32 batch_size)
683 batch = chunk_size * batch <=
n_free ? batch : 1;
729 u32 fl_index, min_size;
755 sf->
size = data_bytes;
777 u32 n_collect = 0, fl_index;
822 pfss = &fs->
slices[slice_index];
832 for (slice_index = 0; slice_index < fs->
n_slices; slice_index++)
856 ASSERT (slice_index < fs->n_slices);
967 f->master_thread_index = ~0;
970 f->ooo_enq =
f->ooo_deq = 0;
992 slice_index = of->master_thread_index;
1001 of->chunks_at_attach = 0;
1005 of->hdr_at_attach = 0;
1025 nf->next = nf->prev = 0;
1044 nf->shr->slice_index = slice_index;
1051 return (
u8 *)
f->shr - (
u8 *)
f->fs_hdr;
1075 return (
u8 *)
c - (
u8 *) fs->
h;
1139 if (n_fds && n_mqs != n_fds)
1147 ASSERT (n_alloced % n_mqs == 0);
1148 size = n_alloced / n_mqs;
1151 for (
i = 0;
i < n_mqs;
i++)
1187 u32 chunk_size,
u32 batch_size)
1195 clib_warning (
"chunk size out of range %d", chunk_size);
1210 u32 rx_fifo_size,
u32 tx_fifo_size,
1213 u32 rx_rounded_data_size, tx_rounded_data_size, pair_size, pairs_to_alloc;
1214 u32 hdrs, pairs_per_slice, alloc_now;
1216 int rx_fl_index, tx_fl_index,
i;
1218 uword space_available;
1221 if (rx_fifo_size == 0 || tx_fifo_size == 0 || *n_fifo_pairs == 0)
1226 clib_warning (
"rx fifo_size out of range %d", rx_fifo_size);
1232 clib_warning (
"tx fifo_size out of range %d", tx_fifo_size);
1236 rx_rounded_data_size = (1 << (
max_log2 (rx_fifo_size)));
1238 tx_rounded_data_size = (1 << (
max_log2 (tx_fifo_size)));
1244 pair_size = 2 * hdrs + rx_rounded_data_size + tx_rounded_data_size;
1246 pairs_to_alloc = space_available / pair_size;
1247 pairs_to_alloc =
clib_min (pairs_to_alloc, *n_fifo_pairs);
1248 pairs_per_slice = pairs_to_alloc / fs->
n_slices;
1249 pairs_per_slice += pairs_to_alloc % fs->
n_slices ? 1 : 0;
1251 if (!pairs_per_slice)
1256 alloc_now =
clib_min (pairs_per_slice, *n_fifo_pairs);
1262 clib_warning (
"rx prealloc failed: pairs %u", alloc_now);
1264 clib_warning (
"tx prealloc failed: pairs %u", alloc_now);
1267 *n_fifo_pairs -= alloc_now;
1306 for (slice_index = 0; slice_index < fs->
n_slices; slice_index++)
1318 u32 count = 0, rounded_size, fl_index;
1366 for (slice_index = 0; slice_index < fs->
n_slices; slice_index++)
1428 for (slice_index = 0; slice_index < fs->
n_slices; slice_index++)
1460 return (in_use * 100) /
size;
1467 return MEMORY_PRESSURE_NO_PRESSURE;
1475 return MEMORY_PRESSURE_NO_MEMORY;
1481 return MEMORY_PRESSURE_HIGH_PRESSURE;
1484 return MEMORY_PRESSURE_LOW_PRESSURE;
1486 return MEMORY_PRESSURE_NO_PRESSURE;
1505 s =
format (s,
"%s",
"private");
1507 s =
format (s,
"%s",
"memfd");
1509 s =
format (s,
"%s",
"shm");
1511 s =
format (s,
"%s",
"unknown");
1521 u32 count, indent, active_fifos, free_fifos;
1523 int verbose __attribute__ ((unused)) = va_arg (*args,
int);
1524 uword est_chunk_bytes, est_free_seg_bytes, free_chunks;
1525 uword chunk_bytes = 0, free_seg_bytes, chunk_size;
1526 uword tracked_cached_bytes;
1527 uword fifo_hdr = 0, reserved;
1535 uword allocated, in_use, virt;
1543 s =
format (s,
"%-20s%10s%15s%15s%15s%15s",
"Name",
"Type",
1544 "HeapSize (M)",
"ActiveFifos",
"FreeFifos",
"Address");
1569 for (slice_index = 0; slice_index < fs->
n_slices; slice_index++)
1588 chunk_bytes +=
count * chunk_size;
1599 usage = (100.0 * in_use) / allocated;
1604 s =
format (s,
"\n%Useg free bytes: %U (%lu) estimated: %U (%lu) reserved:"
1609 s =
format (s,
"%Uchunk free bytes: %U (%lu) estimated: %U (%lu) tracked:"
1614 s =
format (s,
"%Ufifo active: %u hdr free: %u bytes: %U (%u) \n",
1617 s =
format (s,
"%Usegment usage: %.2f%% (%U / %U) virt: %U status: %s\n",
svm_fifo_chunk_t * fsh_alloc_chunk(fifo_segment_header_t *fsh, u32 slice_index, u32 chunk_size)
Allocate chunks in fifo segment.
static int fsh_try_alloc_fifo_hdr_batch(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 batch_size)
u32 master_session_index
session layer session index
static fs_sptr_t fs_sptr(fifo_segment_header_t *fsh, void *p)
static u32 svm_fifo_size(svm_fifo_t *f)
uword fifo_segment_chunk_offset(fifo_segment_t *fs, svm_fifo_chunk_t *c)
static void fs_reset_mem_limit(fifo_segment_t *fs)
uword fifo_segment_cached_bytes(fifo_segment_t *fs)
Fifo segment number of cached bytes.
u32 timeout_in_seconds
Time to wait during attach.
u32 size
size of the fifo in bytes
void fifo_segment_delete(fifo_segment_main_t *sm, fifo_segment_t *s)
static void fss_fifo_free_list_push_list(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, svm_fifo_shared_t *head, svm_fifo_shared_t *tail)
static void pfss_fifo_del_active_list(fifo_slice_private_t *pfss, svm_fifo_t *f)
static void fsh_cached_bytes_sub(fifo_segment_header_t *fsh, uword size)
svm_fifo_t * fifo_segment_alloc_fifo_w_slice(fifo_segment_t *fs, u32 slice_index, u32 data_bytes, fifo_segment_ftype_t ftype)
Allocate fifo in fifo segment.
#define clib_memcpy(d, s, n)
u8 fifo_segment_get_mem_usage(fifo_segment_t *fs)
svm_fifo_t * fs_fifo_alloc(fifo_segment_t *fs, u32 slice_index)
static void fsh_active_fifos_update(fifo_segment_header_t *fsh, int inc)
void fifo_segment_attach_fifo(fifo_segment_t *fs, svm_fifo_t **f, u32 slice_index)
static void fss_chunk_free_list_push_list(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 fl_index, svm_fifo_chunk_t *head, svm_fifo_chunk_t *tail)
svm_fifo_chunk_t * fs_try_alloc_multi_chunk(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 data_bytes)
static void * fs_ptr(fifo_segment_header_t *fsh, fs_sptr_t sp)
fifo_segment_t * fifo_segment_get_segment(fifo_segment_main_t *sm, u32 segment_index)
static uword pointer_to_uword(const void *p)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u8 high_watermark
memory pressure watermark high
static fs_sptr_t fs_chunk_sptr(fifo_segment_header_t *fsh, svm_fifo_chunk_t *c)
svm_msg_q_shared_t * svm_msg_q_init(void *base, svm_msg_q_cfg_t *cfg)
static svm_fifo_chunk_t * fss_chunk_free_list_pop(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 fl_index)
uword fifo_segment_msg_q_offset(fifo_segment_t *fs, u32 mq_index)
Message queue offset on segment.
svm_msg_q_t * fifo_segment_msg_q_attach(fifo_segment_t *fs, uword offset, u32 mq_index)
Attach message queue at fifo segment offset.
uword virtual_mem
Slice sum of all fifo sizes.
svm_fifo_t * fifo_segment_alloc_fifo_w_offset(fifo_segment_t *fs, uword offset)
u8 slice_index
segment slice for fifo
void fifo_segment_info(fifo_segment_t *seg, char **address, size_t *size)
void fifo_segment_detach_fifo(fifo_segment_t *fs, svm_fifo_t **f)
static u32 fs_freelist_index_to_size(u32 fl_index)
fs_sptr_t tail_chunk
tracks chunk where tail lands
u32 fifo_segment_num_free_fifos(fifo_segment_t *fs)
static heap_elt_t * first(heap_header_t *h)
u32 fifo_segment_num_free_chunks(fifo_segment_t *fs, u32 size)
Find number of free chunks of given size.
void clib_mem_bulk_free(clib_mem_bulk_handle_t h, void *p)
#define pool_put(P, E)
Free an object E in pool P.
uword next_baseva
Where to put the next one.
fifo_segment_mem_status_t fifo_segment_determine_status(fifo_segment_t *fs, u8 usage)
int fifo_segment_prealloc_fifo_chunks(fifo_segment_t *fs, u32 slice_index, u32 chunk_size, u32 batch_size)
Try to preallocate fifo chunks on segment.
ssvm_shared_header_t * sh
u8 * format_fifo_segment_type(u8 *s, va_list *args)
static fifo_slice_private_t * fs_slice_private_get(fifo_segment_t *fs, u32 slice_index)
static int fs_try_alloc_fifo_batch(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 fl_index, u32 batch_size)
fs_sptr_t head_chunk
tracks chunk where head lands
uword n_fl_chunk_bytes
Chunk bytes on freelist.
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
static void * fsh_alloc_aligned(fifo_segment_header_t *fsh, uword size, uword align)
enum ssvm_segment_type_ ssvm_segment_type_t
void fifo_segment_collect_chunk(fifo_segment_t *fs, u32 slice_index, svm_fifo_chunk_t *c)
void fsh_collect_chunks(fifo_segment_header_t *fsh, u32 slice_index, svm_fifo_chunk_t *c)
Return chunks to fifo segment.
static void fss_fl_chunk_bytes_sub(fifo_segment_slice_t *fss, uword size)
fs_sptr_t next
next in freelist
#define foreach_segment_mem_status
struct _svm_fifo svm_fifo_t
static uword max_log2(uword x)
static fifo_segment_slice_t * fsh_slice_get(fifo_segment_header_t *fsh, u32 slice_index)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
fs_sptr_t end_chunk
end chunk in fifo chunk list
void fsh_virtual_mem_update(fifo_segment_header_t *fsh, u32 slice_index, int n_bytes)
fifo_segment_mem_status_t fifo_segment_get_mem_status(fifo_segment_t *fs)
void svm_fifo_free_ooo_data(svm_fifo_t *f)
Cleanup fifo ooo data.
void fifo_segment_cleanup(fifo_segment_t *fs)
int fifo_segment_create(fifo_segment_main_t *sm, fifo_segment_create_args_t *a)
Create a fifo segment and initialize as master.
void svm_msg_q_cleanup(svm_msg_q_t *mq)
Cleanup mq's private data.
static u32 fs_freelist_for_size(u32 size)
static int fs_chunk_size_is_valid(fifo_segment_header_t *fsh, u32 size)
static int fsh_try_alloc_chunk_batch(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 fl_index, u32 batch_size)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
void ssvm_delete(ssvm_private_t *ssvm)
svm_msg_q_t * fifo_segment_msg_q_alloc(fifo_segment_t *fs, u32 mq_index, svm_msg_q_cfg_t *cfg)
Allocate message queue on segment.
struct clib_bihash_value offset
template key/value backing page structure
fifo_segment_t * fifo_segment_get_segment_if_valid(fifo_segment_main_t *sm, u32 segment_index)
svm_msg_q_shared_queue_t * shr
pointer to shared queue
static uword fsh_n_cached_bytes(fifo_segment_header_t *fsh)
void fifo_segment_preallocate_fifo_pairs(fifo_segment_t *fs, u32 rx_fifo_size, u32 tx_fifo_size, u32 *n_fifo_pairs)
Pre-allocates fifo pairs in fifo segment.
@ FIFO_SEGMENT_F_MEM_LIMIT
int fifo_segment_attach(fifo_segment_main_t *sm, fifo_segment_create_args_t *a)
Attach as slave to a fifo segment.
void fifo_segment_free_client_fifo(fifo_segment_t *fs, svm_fifo_t *f)
Free fifo allocated by external applications.
uword fifo_segment_fl_chunk_bytes(fifo_segment_t *fs)
Number of bytes on chunk free lists.
static svm_fifo_chunk_t * fss_chunk_free_list_head(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 fl_index)
static u64 round_pow2_u64(u64 x, u64 pow2)
#define FIFO_SEGMENT_MIN_FIFO_SIZE
4kB min fifo size
u8 flags
private fifo segment flags
static void fsh_cached_bytes_add(fifo_segment_header_t *fsh, uword size)
u8 * format_fifo_segment(u8 *s, va_list *args)
Segment format function.
void * fifo_segment_alloc(fifo_segment_t *fs, uword size)
Fifo segment reset mem limit flag.
#define OOO_SEGMENT_INVALID_INDEX
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
int attach_timeout
shm segments attach timeout (sec)
manual_print typedef address
void svm_msg_q_attach(svm_msg_q_t *mq, void *smq_base)
static u8 fs_has_reached_mem_limit(fifo_segment_t *fs)
static svm_fifo_shared_t * fs_try_alloc_fifo(fifo_segment_header_t *fsh, u32 slice_index, u32 data_bytes)
Try to allocate new fifo.
clib_mem_bulk_handle_t clib_mem_bulk_init(u32 elt_sz, u32 align, u32 min_elts_per_chunk)
fs_sptr_t next
pointer to next chunk in linked-lists
#define clib_atomic_fetch_add_rel(a, b)
#define CLIB_CACHE_LINE_BYTES
svm_fifo_t * fifo_segment_duplicate_fifo(fifo_segment_t *fs, svm_fifo_t *f)
void svm_fifo_init(svm_fifo_t *f, u32 size)
Initialize fifo.
u8 n_slices
number of fifo segment slices
svm_fifo_chunk_t * fifo_segment_alloc_chunk_w_slice(fifo_segment_t *fs, u32 slice_index, u32 chunk_size)
static void pfss_fifo_add_active_list(fifo_slice_private_t *pfss, svm_fifo_t *f)
uword svm_msg_q_size_to_alloc(svm_msg_q_cfg_t *cfg)
#define clib_atomic_fetch_sub_rel(a, b)
static uword fs_virtual_mem(fifo_segment_t *fs)
fs_sptr_t start_chunk
first chunk in fifo chunk list
#define clib_atomic_fetch_add_relax(a, b)
ssvm_private_t ssvm
ssvm segment data
#define vec_free(V)
Free vector's memory (no header).
u32 num_chunks[FS_CHUNK_VEC_LEN]
Allocated chunks by chunk size.
u32 fifo_segment_num_fifos(fifo_segment_t *fs)
Get number of active fifos.
static uword fss_fl_chunk_bytes(fifo_segment_slice_t *fss)
void svm_msg_q_set_eventfd(svm_msg_q_t *mq, int fd)
Set event fd for queue.
fs_sptr_t free_fifos
Freelists of fifo shared hdrs
template key/value backing page structure
struct fifo_segment_slice_ fifo_segment_slice_t
void fifo_segment_free_fifo(fifo_segment_t *fs, svm_fifo_t *f)
Free fifo allocated in fifo segment.
void fifo_segment_main_init(fifo_segment_main_t *sm, u64 baseva, u32 timeout_in_seconds)
#define FS_CHUNK_VEC_LEN
number of chunk sizes
static u32 fsh_n_active_fifos(fifo_segment_header_t *fsh)
static void fss_fifo_free_list_push(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, svm_fifo_shared_t *sf)
description fragment has unexpected format
int ssvm_server_init(ssvm_private_t *ssvm, ssvm_segment_type_t type)
void * clib_mem_bulk_alloc(clib_mem_bulk_handle_t h)
static void fss_fl_chunk_bytes_add(fifo_segment_slice_t *fss, uword size)
void svm_fifo_free_chunk_lookup(svm_fifo_t *f)
Cleanup fifo chunk lookup rb tree.
#define clib_atomic_fetch_sub_relax(a, b)
#define SVM_FIFO_INVALID_INDEX
ssvm_segment_type_t ssvm_type(const ssvm_private_t *ssvm)
u8 low_watermark
memory pressure watermark low
#define clib_atomic_load_relax_n(a)
u32 fifo_segment_index(fifo_segment_main_t *sm, fifo_segment_t *s)
#define CLIB_MEM_UNPOISON(a, s)
uword max_byte_index
max byte index for segment
#define vec_foreach(var, vec)
Vector iterator.
svm_fifo_shared_t * fss_fifo_free_list_pop(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss)
uword fifo_segment_available_bytes(fifo_segment_t *fs)
int fifo_segment_init(fifo_segment_t *fs)
Initialize fifo segment shared header.
#define FIFO_SEGMENT_MAX_FIFO_SIZE
2GB max fifo size
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static svm_fifo_chunk_t * fs_chunk_ptr(fifo_segment_header_t *fsh, fs_sptr_t cp)
static svm_fifo_chunk_t * fsh_try_alloc_chunk(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 data_bytes)
uword fifo_segment_size(fifo_segment_t *fs)
Fifo segment allocated size.
svm_msg_q_t * mqs
private vec of attached mqs
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
uword fifo_segment_free_bytes(fifo_segment_t *fs)
Fifo segment estimate of number of free bytes.
static void fsh_slice_collect_chunks(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, svm_fifo_chunk_t *c)
static int fss_chunk_fl_index_is_valid(fifo_segment_slice_t *fss, u32 fl_index)
#define uword_to_pointer(u, type)
#define clib_atomic_cmp_and_swap_acq_relax(addr, exp, new, weak)
fs_sptr_t free_chunks[FS_CHUNK_VEC_LEN]
Free chunks by size.
#define clib_warning(format, args...)
fifo_segment_t * segments
pool of fifo segments
fifo_slice_private_t * slices
private slice information
#define FIFO_SEGMENT_MIN_LOG2_FIFO_SIZE
4kB min fifo size
void fs_fifo_free(fifo_segment_t *fs, svm_fifo_t *f, u32 slice_index)
#define clib_atomic_load_acq_n(a)
svm_fifo_t * active_fifos
Linked list of active RX fifos.
uword fifo_segment_fifo_offset(svm_fifo_t *f)
u8 * ssvm_name(const ssvm_private_t *ssvm)
int fifo_segment_prealloc_fifo_hdrs(fifo_segment_t *fs, u32 slice_index, u32 batch_size)
Try to preallocate fifo headers.
static uword min_log2(uword x)
fifo_segment_header_t * h
fifo segment data
void clib_mem_bulk_destroy(clib_mem_bulk_handle_t h)
static uword fsh_n_free_bytes(fifo_segment_header_t *fsh)
void fifo_segment_msg_qs_discover(fifo_segment_t *fs, int *fds, u32 n_fds)
Discover mqs on mq only segment.
u8 fifo_segment_has_fifos(fifo_segment_t *fs)
static void fss_chunk_free_list_push(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 fl_index, svm_fifo_chunk_t *c)
svm_fifo_t * fifo_segment_get_slice_fifo_list(fifo_segment_t *fs, u32 slice_index)
clib_mem_bulk_handle_t fifos
Bulk fifo allocator.
static u32 fs_slice_num_free_fifos(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss)
int ssvm_client_init(ssvm_private_t *ssvm, ssvm_segment_type_t type)
static char * fifo_segment_mem_status_strings[]
svm_msg_q_queue_t q
queue for exchanging messages
#define FIFO_SEGMENT_ALLOC_BATCH_SIZE
static u32 fs_slice_num_free_chunks(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss, u32 size)
static void * fsh_alloc(fifo_segment_header_t *fsh, uword size)
static svm_fifo_shared_t * fsh_try_alloc_fifo_hdr(fifo_segment_header_t *fsh, fifo_segment_slice_t *fss)
fifo_segment_mem_status_t