66 return (seg - sm->segments);
84 memset (fs, 0xfb,
sizeof (*fs));
136 ASSERT (sm->segments_rwlock->n_readers > 0);
156 u32 rnd_margin = 128 << 10, seg_index;
158 uword baseva = (
u64) ~ 0, alloc_size;
166 if (!props->add_segment && !segment_size)
169 return VNET_API_ERROR_INVALID_VALUE;
184 memset (seg, 0,
sizeof (*seg));
189 segment_size = segment_size ? segment_size : props->add_segment_size;
193 alloc_size = segment_size + rnd_margin;
202 seg_name =
format (0,
"%s%c",
"process-private-segment", 0);
210 clib_warning (
"svm_master_init ('%v', %u) failed", seg_name,
224 seg_index = seg - sm->segments;
238 memset (sm, 0,
sizeof (*sm));
249 u32 prealloc_fifo_pairs)
251 u32 rx_fifo_size, tx_fifo_size, pair_size;
252 u32 rx_rounded_data_size, tx_rounded_data_size;
253 u64 approx_total_size, max_seg_size =
257 u32 approx_segment_count;
263 if (prealloc_fifo_pairs)
266 rx_rounded_data_size = (1 << (
max_log2 (props->rx_fifo_size)));
267 tx_rounded_data_size = (1 << (
max_log2 (props->tx_fifo_size)));
269 rx_fifo_size =
sizeof (
svm_fifo_t) + rx_rounded_data_size;
270 tx_fifo_size =
sizeof (
svm_fifo_t) + tx_rounded_data_size;
271 pair_size = rx_fifo_size + tx_fifo_size;
273 approx_total_size = (
u64) prealloc_fifo_pairs *pair_size;
274 if (first_seg_size > approx_total_size)
275 max_seg_size = first_seg_size;
276 approx_segment_count = (approx_total_size + (max_seg_size - 1))
280 for (i = 0; i < approx_segment_count + 1; i++)
297 &prealloc_fifo_pairs);
299 if (prealloc_fifo_pairs == 0)
369 if (fifo->master_thread_index == 255)
373 fifo->master_session_index);
378 fifo->master_thread_index);
414 segment_manager_del_segment (sm, fifo_segment);
422 memset (sm, 0xfe,
sizeof (*sm));
441 u32 rx_fifo_size,
u32 tx_fifo_size,
481 u32 * fifo_segment_index)
484 int alloc_fail = 1, rv = 0, new_fs_index;
486 u8 added_a_segment = 0;
514 ASSERT (rx_fifo && tx_fifo);
516 (*tx_fifo)->segment_manager = sm_index;
517 (*rx_fifo)->segment_manager = sm_index;
522 &fifo_segment->
ssvm);
531 if (props->add_segment)
535 clib_warning (
"Added a segment, still can't allocate a fifo");
537 return SESSION_ERROR_NEW_SEG_NO_SPACE;
542 return SESSION_ERROR_SEG_CREATE;
554 clib_warning (
"Can't add new seg and no space to allocate fifos!");
555 return SESSION_ERROR_NO_SPACE;
588 if (segment_index != 0 || !sm->first_is_protected)
666 u8 show_segments = 0, verbose = 0;
676 else if (
unformat (input,
"verbose"))
691 vlib_cli_output (vm,
"%-10d%=15d%=12d", segment_manager_index(sm),
692 sm->app_index, pool_elts (sm->segments));
700 "HeapSize (M)",
"ActiveFifos",
"FreeFifos",
"Address");
704 segment_manager_foreach_segment_w_lock (seg, sm, ({
705 svm_fifo_segment_info (seg, &address, &size);
706 active_fifos = svm_fifo_segment_num_fifos (seg);
707 free_fifos = svm_fifo_segment_num_free_fifos (seg, ~0 );
708 vlib_cli_output (vm,
"%-15v%15U%15llu%15u%15u%15llx",
709 ssvm_name (&seg->ssvm), format_svm_fifo_segment_type,
710 seg, size >> 20ULL, active_fifos, free_fifos,
713 vlib_cli_output (vm,
"%U", format_svm_fifo_segment, seg, verbose);
725 .path =
"show segment-manager",
726 .short_help =
"show segment-manager [segments][verbose]",
segment_manager_main_t segment_manager_main
static void clib_rwlock_reader_lock(clib_rwlock_t *p)
svm_queue_t * segment_manager_alloc_queue(svm_fifo_segment_private_t *segment, u32 queue_size)
Allocates shm queue in the first segment.
void segment_manager_segment_reader_unlock(segment_manager_t *sm)
static segment_manager_t * segment_manager_get_if_valid(u32 index)
static void clib_rwlock_writer_lock(clib_rwlock_t *p)
struct _segment_manager_properties segment_manager_properties_t
segment_manager_properties_t * application_get_segment_manager_properties(u32 app_index)
static u32 default_segment_size
static void clib_rwlock_free(clib_rwlock_t *p)
static u32 default_app_evt_queue_size
clib_valloc_main_t va_allocator
Virtual address allocator.
#define FIFO_SEGMENT_F_IS_PREALLOCATED
ssvm_shared_header_t * sh
void segment_manager_dealloc_fifos(u32 segment_index, svm_fifo_t *rx_fifo, svm_fifo_t *tx_fifo)
segment_manager_properties_t * segment_manager_properties_init(segment_manager_properties_t *props)
#define segment_manager_foreach_segment_w_lock(VAR, SM, BODY)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
void svm_fifo_segment_preallocate_fifo_pairs(svm_fifo_segment_private_t *s, u32 rx_fifo_size, u32 tx_fifo_size, u32 *n_fifo_pairs)
Pre-allocates fifo pairs in fifo segment.
segment_manager_t * segment_managers
Pool of segment managers.
int segment_manager_init(segment_manager_t *sm, u32 first_seg_size, u32 prealloc_fifo_pairs)
Initializes segment manager based on options provided.
void ssvm_delete(ssvm_private_t *ssvm)
struct _svm_fifo svm_fifo_t
svm_queue_t * svm_queue_init(int nels, int elsize, int consumer_pid, int signal_when_queue_non_empty)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static u8 segment_manager_app_detached(segment_manager_t *sm)
svm_fifo_segment_private_t * segment_manager_get_segment_w_lock(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager's pool and acquires reader lock.
static void * ssvm_push_heap(ssvm_shared_header_t *sh)
#define clib_error_return(e, args...)
struct _stream_session_t stream_session_t
static void segment_manager_lock_and_del_segment(segment_manager_t *sm, u32 fs_index)
Removes segment after acquiring writer lock.
int ssvm_master_init(ssvm_private_t *ssvm, ssvm_segment_type_t type)
static void ssvm_pop_heap(void *oldheap)
segment_manager_t * segment_manager_new()
static heap_elt_t * first(heap_header_t *h)
#define svm_fifo_segment_flags(_seg)
int application_add_segment_notify(u32 app_index, ssvm_private_t *fs)
Send an API message to the external app, to map new segment.
int segment_manager_alloc_session_fifos(segment_manager_t *sm, svm_fifo_t **rx_fifo, svm_fifo_t **tx_fifo, u32 *fifo_segment_index)
static svm_fifo_t * svm_fifo_segment_get_fifo_list(svm_fifo_segment_private_t *fifo_segment)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static void clib_rwlock_init(clib_rwlock_t *p)
static void clib_rwlock_reader_unlock(clib_rwlock_t *p)
void segment_manager_app_detach(segment_manager_t *sm)
void segment_manager_dealloc_queue(segment_manager_t *sm, svm_queue_t *q)
Frees shm queue allocated in the first segment.
#define pool_put(P, E)
Free an object E in pool P.
svm_fifo_segment_private_t * segment_manager_get_segment(segment_manager_t *sm, u32 segment_index)
Reads a segment from the segment manager's pool without lock.
u8 segment_manager_has_fifos(segment_manager_t *sm)
segment_manager_properties_t * segment_manager_properties_get(segment_manager_t *sm)
uword size
size in bytes of this chunk
void segment_manager_del_segment(segment_manager_t *sm, svm_fifo_segment_private_t *fs)
Remove segment without lock.
int segment_manager_add_segment(segment_manager_t *sm, u32 segment_size)
Adds segment to segment manager's pool.
static stream_session_t * session_get(u32 si, u32 thread_index)
uword baseva
base VA for this chunk
#define SEGMENT_MANAGER_INVALID_APP_INDEX
static u8 svm_fifo_segment_has_fifos(svm_fifo_segment_private_t *fifo_segment)
static void clib_rwlock_writer_unlock(clib_rwlock_t *p)
#define clib_warning(format, args...)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
int application_local_session_disconnect_w_index(u32 app_index, u32 ls_index)
int segment_manager_try_alloc_fifos(svm_fifo_segment_private_t *fifo_segment, u32 rx_fifo_size, u32 tx_fifo_size, svm_fifo_t **rx_fifo, svm_fifo_t **tx_fifo)
static u32 segment_manager_index(segment_manager_t *sm)
void svm_queue_free(svm_queue_t *q)
#define VLIB_CLI_COMMAND(x,...)
uword clib_valloc_alloc(clib_valloc_main_t *vam, uword size, int os_out_of_memory_on_failure)
Allocate virtual space.
void segment_manager_init_del(segment_manager_t *sm)
void segment_manager_main_init(segment_manager_main_init_args_t *a)
static u32 segment_manager_segment_index(segment_manager_t *sm, svm_fifo_segment_private_t *seg)
void stream_session_disconnect(stream_session_t *s)
Initialize session disconnect.
void svm_fifo_segment_free_fifo(svm_fifo_segment_private_t *s, svm_fifo_t *f, svm_fifo_segment_freelist_t list_index)
void segment_manager_segment_writer_unlock(segment_manager_t *sm)
void segment_manager_del(segment_manager_t *sm)
Removes segment manager.
static uword max_log2(uword x)
static u32 segment_name_counter
Counter used to build segment names.
void segment_manager_del_sessions(segment_manager_t *sm)
Initiate disconnects for all sessions 'owned' by a segment manager.
uword clib_valloc_free(clib_valloc_main_t *vam, uword baseva)
Free virtual space.
struct _segment_manager segment_manager_t
struct _svm_queue svm_queue_t
int svm_fifo_segment_init(svm_fifo_segment_private_t *s)
Initialize svm fifo segment shared header.
void clib_valloc_init(clib_valloc_main_t *vam, clib_valloc_chunk_t *template, int need_lock)
Initialize a virtual memory allocation arena.
static u32 vlib_num_workers()
static clib_error_t * segment_manager_show_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static u32 default_fifo_size
Default fifo and segment size.
uword clib_mem_get_page_size(void)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
svm_fifo_t * svm_fifo_segment_alloc_fifo(svm_fifo_segment_private_t *s, u32 data_size_in_bytes, svm_fifo_segment_freelist_t list_index)
Allocate fifo in svm segment.
ssvm_segment_type_t ssvm_type(const ssvm_private_t *ssvm)
static uword pool_elts(void *v)
Number of active elements in a pool.