X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fsegment_manager.c;h=9c33e35e8f0a0202e77286289cfdda9f593af392;hb=refs%2Fchanges%2F06%2F22406%2F4;hp=47c7f5635428e9c015585ce1504cf13083708e90;hpb=88001c64e9e5d0dc08e303857ca34687454ebf10;p=vpp.git diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index 47c7f563542..9c33e35e8f0 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -102,7 +102,7 @@ segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) } /* - * Allocate fifo segment and lock if needed + * Allocate fifo segment and grab lock if needed */ if (vlib_num_workers ()) clib_rwlock_writer_lock (&sm->segments_rwlock); @@ -110,11 +110,14 @@ segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) pool_get_zero (sm->segments, fs); /* - * Initialize ssvm segment and svm fifo private header + * Allocate ssvm segment */ 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); + /* Protect against segment size u32 wrap */ + segment_size = clib_max (segment_size + page_size - 1, segment_size); + segment_size = segment_size & ~(page_size - 1); + if (props->segment_type != SSVM_SEGMENT_PRIVATE) { seg_name = format (0, "%d-%d%c", getpid (), smm->seg_name_counter++, 0); @@ -128,7 +131,7 @@ segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) } } else - seg_name = format (0, "%s%c", "process-private-segment", 0); + seg_name = format (0, "%s%c", "process-private", 0); fs->ssvm.ssvm_size = segment_size; fs->ssvm.name = seg_name; @@ -145,6 +148,9 @@ segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) goto done; } + /* + * Initialize fifo segment + */ fifo_segment_init (fs); /* @@ -274,7 +280,6 @@ segment_manager_get_segment_w_lock (segment_manager_t * sm, u32 segment_index) void segment_manager_segment_reader_unlock (segment_manager_t * sm) { - ASSERT (sm->segments_rwlock->n_readers > 0); clib_rwlock_reader_unlock (&sm->segments_rwlock); } @@ -627,8 +632,8 @@ alloc_check: void segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo, svm_fifo_t * tx_fifo) { - fifo_segment_t *fs; segment_manager_t *sm; + fifo_segment_t *fs; u32 segment_index; if (!rx_fifo || !tx_fifo) @@ -669,6 +674,50 @@ segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo, svm_fifo_t * tx_fifo) segment_manager_segment_reader_unlock (sm); } +int +segment_manager_grow_fifo (segment_manager_t * sm, svm_fifo_t * f, u32 size) +{ + fifo_segment_t *fs; + int rv; + + fs = segment_manager_get_segment_w_lock (sm, f->segment_index); + rv = fifo_segment_grow_fifo (fs, f, size); + segment_manager_segment_reader_unlock (sm); + + return rv; +} + +int +segment_manager_collect_fifo_chunks (segment_manager_t * sm, svm_fifo_t * f) +{ + fifo_segment_t *fs; + int rv; + + fs = segment_manager_get_segment_w_lock (sm, f->segment_index); + rv = fifo_segment_collect_fifo_chunks (fs, f); + segment_manager_segment_reader_unlock (sm); + + return rv; +} + +int +segment_manager_shrink_fifo (segment_manager_t * sm, svm_fifo_t * f, u32 size, + u8 is_producer) +{ + int rv; + + rv = svm_fifo_reduce_size (f, size, is_producer); + + /* Nothing to collect at this point */ + if (!is_producer) + return rv; + + if (f->flags & SVM_FIFO_F_COLLECT_CHUNKS) + segment_manager_collect_fifo_chunks (sm, f); + + return rv; +} + u32 segment_manager_evt_q_expected_size (u32 q_len) { @@ -715,6 +764,7 @@ segment_manager_alloc_queue (fifo_segment_t * segment, oldheap = ssvm_push_heap (segment->ssvm.sh); q = svm_msg_q_alloc (cfg); + fifo_segment_update_free_bytes (segment); ssvm_pop_heap (oldheap); if (props->use_mq_eventfd) @@ -776,13 +826,9 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { segment_manager_main_t *smm = &sm_main; - fifo_segment_t *seg; - segment_manager_t *sm; u8 show_segments = 0, verbose = 0; - char *address; - size_t size; - u32 active_fifos; - u32 free_fifos; + segment_manager_t *sm; + fifo_segment_t *seg; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -811,21 +857,12 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, } if (show_segments) { - vlib_cli_output (vm, "%-15s%15s%15s%15s%15s%15s", "Name", "Type", - "HeapSize (M)", "ActiveFifos", "FreeFifos", "Address"); + vlib_cli_output (vm, "%U", format_fifo_segment, 0, verbose); /* *INDENT-OFF* */ pool_foreach (sm, smm->segment_managers, ({ segment_manager_foreach_segment_w_lock (seg, sm, ({ - fifo_segment_info (seg, &address, &size); - active_fifos = fifo_segment_num_fifos (seg); - free_fifos = fifo_segment_num_free_fifos (seg, ~0 /* size */); - vlib_cli_output (vm, "%-15v%15U%15llu%15u%15u%15llx", - ssvm_name (&seg->ssvm), format_fifo_segment_type, - seg, size >> 20ULL, active_fifos, free_fifos, - address); - if (verbose) - vlib_cli_output (vm, "%U", format_fifo_segment, seg, verbose); + vlib_cli_output (vm, "%U", format_fifo_segment, seg, verbose); })); })); /* *INDENT-ON* */