X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fsegment_manager.c;h=0a54b96a1257979baedbf09aabb653cce999be91;hb=f22f4e562e1b922cff036ef628b77fd2d479d015;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..0a54b96a125 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -54,6 +54,7 @@ segment_manager_props_init (segment_manager_props_t * props) props->rx_fifo_size = sm_main.default_fifo_size; props->tx_fifo_size = sm_main.default_fifo_size; props->evt_q_size = sm_main.default_app_mq_size; + props->n_slices = vlib_num_workers () + 1; return props; } @@ -82,11 +83,11 @@ segment_manager_segment_index (segment_manager_t * sm, fifo_segment_t * seg) * to avoid affecting any of the segments pool readers. */ int -segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) +segment_manager_add_segment (segment_manager_t * sm, uword segment_size) { + uword baseva = (uword) ~ 0ULL, alloc_size, page_size; + u32 rnd_margin = 128 << 10, fs_index = ~0; segment_manager_main_t *smm = &sm_main; - u32 rnd_margin = 128 << 10, fs_index = ~0, page_size; - uword baseva = (uword) ~ 0ULL, alloc_size; segment_manager_props_t *props; fifo_segment_t *fs; u8 *seg_name; @@ -102,7 +103,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 +111,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 +132,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 +149,10 @@ segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) goto done; } + /* + * Initialize fifo segment + */ + fs->n_slices = props->n_slices; fifo_segment_init (fs); /* @@ -274,7 +282,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); } @@ -300,7 +307,7 @@ segment_manager_alloc (void) * Returns error if ssvm segment(s) allocation fails. */ int -segment_manager_init (segment_manager_t * sm, u32 first_seg_size, +segment_manager_init (segment_manager_t * sm, uword first_seg_size, u32 prealloc_fifo_pairs) { u32 rx_fifo_size, tx_fifo_size, pair_size; @@ -465,30 +472,34 @@ segment_manager_has_fifos (segment_manager_t * sm) void segment_manager_del_sessions (segment_manager_t * sm) { - fifo_segment_t *fifo_segment; session_handle_t *handles = 0, *handle; + fifo_segment_t *fs; session_t *session; - svm_fifo_t *fifo; + int slice_index; + svm_fifo_t *f; ASSERT (pool_elts (sm->segments) != 0); /* Across all fifo segments used by the server */ /* *INDENT-OFF* */ - segment_manager_foreach_segment_w_lock (fifo_segment, sm, ({ - fifo = fifo_segment_get_fifo_list (fifo_segment); - - /* - * Remove any residual sessions from the session lookup table - * Don't bother deleting the individual fifos, we're going to - * throw away the fifo segment in a minute. - */ - while (fifo) + segment_manager_foreach_segment_w_lock (fs, sm, ({ + for (slice_index = 0; slice_index < fs->n_slices; slice_index++) { - session = session_get_if_valid (fifo->master_session_index, - fifo->master_thread_index); - if (session) - vec_add1 (handles, session_handle (session)); - fifo = fifo->next; + f = fifo_segment_get_slice_fifo_list (fs, slice_index); + + /* + * Remove any residual sessions from the session lookup table + * Don't bother deleting the individual fifos, we're going to + * throw away the fifo segment in a minute. + */ + while (f) + { + session = session_get_if_valid (f->master_session_index, + f->master_thread_index); + if (session) + vec_add1 (handles, session_handle (session)); + f = f->next; + } } /* Instead of removing the segment, test when cleaning up disconnected @@ -503,16 +514,19 @@ segment_manager_del_sessions (segment_manager_t * sm) int segment_manager_try_alloc_fifos (fifo_segment_t * fifo_segment, + u32 thread_index, u32 rx_fifo_size, u32 tx_fifo_size, svm_fifo_t ** rx_fifo, svm_fifo_t ** tx_fifo) { rx_fifo_size = clib_max (rx_fifo_size, sm_main.default_fifo_size); - *rx_fifo = fifo_segment_alloc_fifo (fifo_segment, rx_fifo_size, - FIFO_SEGMENT_RX_FIFO); + *rx_fifo = fifo_segment_alloc_fifo_w_slice (fifo_segment, thread_index, + rx_fifo_size, + FIFO_SEGMENT_RX_FIFO); tx_fifo_size = clib_max (tx_fifo_size, sm_main.default_fifo_size); - *tx_fifo = fifo_segment_alloc_fifo (fifo_segment, tx_fifo_size, - FIFO_SEGMENT_TX_FIFO); + *tx_fifo = fifo_segment_alloc_fifo_w_slice (fifo_segment, thread_index, + tx_fifo_size, + FIFO_SEGMENT_TX_FIFO); if (*rx_fifo == 0) { @@ -539,6 +553,7 @@ segment_manager_try_alloc_fifos (fifo_segment_t * fifo_segment, int segment_manager_alloc_session_fifos (segment_manager_t * sm, + u32 thread_index, svm_fifo_t ** rx_fifo, svm_fifo_t ** tx_fifo) { @@ -558,6 +573,7 @@ segment_manager_alloc_session_fifos (segment_manager_t * sm, /* *INDENT-OFF* */ segment_manager_foreach_segment_w_lock (fs, sm, ({ alloc_fail = segment_manager_try_alloc_fifos (fs, + thread_index, props->rx_fifo_size, props->tx_fifo_size, rx_fifo, tx_fifo); @@ -611,7 +627,8 @@ alloc_check: return SESSION_ERROR_SEG_CREATE; } fs = segment_manager_get_segment_w_lock (sm, new_fs_index); - alloc_fail = segment_manager_try_alloc_fifos (fs, props->rx_fifo_size, + alloc_fail = segment_manager_try_alloc_fifos (fs, thread_index, + props->rx_fifo_size, props->tx_fifo_size, rx_fifo, tx_fifo); added_a_segment = 1; @@ -627,8 +644,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) @@ -715,6 +732,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 +794,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 +825,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* */ @@ -846,11 +851,13 @@ VLIB_CLI_COMMAND (segment_manager_show_command, static) = void segment_manager_format_sessions (segment_manager_t * sm, int verbose) { - fifo_segment_t *fifo_segment; vlib_main_t *vm = vlib_get_main (); app_worker_t *app_wrk; + fifo_segment_t *fs; const u8 *app_name; - u8 *s = 0; + int slice_index; + u8 *s = 0, *str; + svm_fifo_t *f; if (!sm) { @@ -868,35 +875,35 @@ segment_manager_format_sessions (segment_manager_t * sm, int verbose) clib_rwlock_reader_lock (&sm->segments_rwlock); /* *INDENT-OFF* */ - pool_foreach (fifo_segment, sm->segments, ({ - svm_fifo_t *fifo; - u8 *str; - - fifo = fifo_segment_get_fifo_list (fifo_segment); - while (fifo) + pool_foreach (fs, sm->segments, ({ + for (slice_index = 0; slice_index < fs->n_slices; slice_index++) { - u32 session_index, thread_index; - session_t *session; - - session_index = fifo->master_session_index; - thread_index = fifo->master_thread_index; - - session = session_get (session_index, thread_index); - str = format (0, "%U", format_session, session, verbose); - - if (verbose) - s = format (s, "%-40s%-20s%-15u%-10u", str, app_name, - app_wrk->api_client_index, app_wrk->connects_seg_manager); - else - s = format (s, "%-40s%-20s", str, app_name); - - vlib_cli_output (vm, "%v", s); - vec_reset_length (s); - vec_free (str); - - fifo = fifo->next; + f = fifo_segment_get_slice_fifo_list (fs, slice_index); + while (f) + { + u32 session_index, thread_index; + session_t *session; + + session_index = f->master_session_index; + thread_index = f->master_thread_index; + + session = session_get (session_index, thread_index); + str = format (0, "%U", format_session, session, verbose); + + if (verbose) + s = format (s, "%-40s%-20s%-15u%-10u", str, app_name, + app_wrk->api_client_index, app_wrk->connects_seg_manager); + else + s = format (s, "%-40s%-20s", str, app_name); + + vlib_cli_output (vm, "%v", s); + vec_reset_length (s); + vec_free (str); + + f = f->next; + } + vec_free (s); } - vec_free (s); })); /* *INDENT-ON* */