-/**
- * Adds segment to segment manager's pool
- *
- * If needed a writer's lock is acquired before allocating a new segment
- * to avoid affecting any of the segments pool readers.
- */
-int
-segment_manager_add_segment (segment_manager_t * sm, u32 segment_size)
-{
- segment_manager_main_t *smm = &segment_manager_main;
- u32 rnd_margin = 128 << 10, seg_index = ~0, page_size;
- segment_manager_properties_t *props;
- uword baseva = (uword) ~ 0ULL, alloc_size;
- svm_fifo_segment_private_t *seg;
- u8 *seg_name;
- int rv;
-
- props = segment_manager_properties_get (sm);
-
- /* Not configured for addition of new segments and not first */
- if (!props->add_segment && !segment_size)
- {
- clib_warning ("cannot allocate new segment");
- return VNET_API_ERROR_INVALID_VALUE;
- }
-
- /*
- * Allocate fifo segment and lock if needed
- */
- if (vlib_num_workers ())
- clib_rwlock_writer_lock (&sm->segments_rwlock);
-
- pool_get_zero (sm->segments, seg);
-
- /*
- * Initialize ssvm segment and svm fifo private header
- */
- segment_size = segment_size ? segment_size : props->add_segment_size;
- page_size = clib_mem_get_page_size ();
- segment_size = (segment_size + page_size - 1) & ~(page_size - 1);
- if (props->segment_type != SSVM_SEGMENT_PRIVATE)
- {
- seg_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0);
- alloc_size = (uword) segment_size + rnd_margin;
- baseva = clib_valloc_alloc (&smm->va_allocator, alloc_size, 0);
- if (!baseva)
- {
- clib_warning ("out of space for segments");
- pool_put (sm->segments, seg);
- goto done;
- }
- }
- else
- seg_name = format (0, "%s%c", "process-private-segment", 0);
-
- seg->ssvm.ssvm_size = segment_size;
- seg->ssvm.name = seg_name;
- seg->ssvm.requested_va = baseva;
-
- if ((rv = ssvm_master_init (&seg->ssvm, props->segment_type)))
- {
- clib_warning ("svm_master_init ('%v', %u) failed", seg_name,
- segment_size);
-
- if (props->segment_type != SSVM_SEGMENT_PRIVATE)
- clib_valloc_free (&smm->va_allocator, baseva);
- pool_put (sm->segments, seg);
- goto done;
- }
-
- svm_fifo_segment_init (seg);
-
- /*
- * Save segment index before dropping lock, if any held
- */
- seg_index = seg - sm->segments;
-
-done:
-
- if (vlib_num_workers ())
- clib_rwlock_writer_unlock (&sm->segments_rwlock);
-
- return seg_index;
-}
-