diff options
-rw-r--r-- | src/svm/svm_fifo_segment.c | 101 | ||||
-rw-r--r-- | src/svm/svm_fifo_segment.h | 4 | ||||
-rw-r--r-- | src/vnet/session/segment_manager.c | 54 | ||||
-rw-r--r-- | src/vnet/tcp/builtin_client.c | 14 | ||||
-rw-r--r-- | src/vnet/tcp/builtin_proxy.c | 16 | ||||
-rw-r--r-- | src/vnet/tcp/builtin_server.c | 16 |
6 files changed, 176 insertions, 29 deletions
diff --git a/src/svm/svm_fifo_segment.c b/src/svm/svm_fifo_segment.c index 97d9976b39e..3bdd2b28ebb 100644 --- a/src/svm/svm_fifo_segment.c +++ b/src/svm/svm_fifo_segment.c @@ -221,13 +221,13 @@ svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) u8 **heaps = 0; mheap_t *heap_header; int segment_count = 1; + u32 rnd_size = 0; int i; if (a->private_segment_count && a->private_segment_size) { u8 *heap; u32 pagesize = clib_mem_get_page_size (); - u32 rnd_size; rnd_size = (a->private_segment_size + (pagesize - 1)) & ~pagesize; for (i = 0; i < a->private_segment_count; i++) @@ -246,7 +246,8 @@ svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) } /* Spread preallocated fifo pairs across segments */ - a->preallocated_fifo_pairs /= segment_count; + a->preallocated_fifo_pairs = + (a->preallocated_fifo_pairs + segment_count - 1) / segment_count; /* Allocate segments */ for (i = 0; i < segment_count; i++) @@ -254,7 +255,7 @@ svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) pool_get (sm->segments, s); memset (s, 0, sizeof (*s)); - s->ssvm.ssvm_size = ~0; + s->ssvm.ssvm_size = rnd_size; s->ssvm.i_am_master = 1; s->ssvm.my_pid = getpid (); s->ssvm.name = format (0, "%s%c", a->segment_name, 0); @@ -536,6 +537,100 @@ svm_fifo_segment_num_fifos (svm_fifo_segment_private_t * fifo_segment) return fifo_segment->h->n_active_fifos; } +u32 +svm_fifo_segment_num_free_fifos (svm_fifo_segment_private_t * fifo_segment, + u32 fifo_size_in_bytes) +{ + ssvm_shared_header_t *sh; + svm_fifo_segment_header_t *fsh; + svm_fifo_t *f; + int i; + u32 count = 0, rounded_data_size, freelist_index; + + sh = fifo_segment->ssvm.sh; + fsh = (svm_fifo_segment_header_t *) sh->opaque[0]; + + /* Count all free fifos? */ + if (fifo_size_in_bytes == ~0) + { + for (i = 0; i < vec_len (fsh->free_fifos); i++) + { + f = fsh->free_fifos[i]; + if (f == 0) + continue; + + while (f) + { + f = f->next; + count++; + } + } + return count; + } + + rounded_data_size = (1 << (max_log2 (fifo_size_in_bytes))); + freelist_index = max_log2 (rounded_data_size) + - max_log2 (FIFO_SEGMENT_MIN_FIFO_SIZE); + + if (freelist_index > vec_len (fsh->free_fifos)) + return 0; + + f = fsh->free_fifos[freelist_index]; + if (f == 0) + return 0; + + while (f) + { + f = f->next; + count++; + } + return count; +} + +/** + * Segment format function + */ +u8 * +format_svm_fifo_segment (u8 * s, va_list * args) +{ + svm_fifo_segment_private_t *sp + = va_arg (*args, svm_fifo_segment_private_t *); + int verbose = va_arg (*args, int); + ssvm_shared_header_t *sh; + svm_fifo_segment_header_t *fsh; + svm_fifo_t *f; + int i; + u32 count; + uword indent = format_get_indent (s) + 2; + + sh = sp->ssvm.sh; + fsh = (svm_fifo_segment_header_t *) sh->opaque[0]; + + s = format (s, "%USegment Heap: %U\n", format_white_space, indent, + format_mheap, sh->heap, verbose); + s = format (s, "%U segment has %u active fifos\n", + format_white_space, indent, svm_fifo_segment_num_fifos (sp)); + + for (i = 0; i < vec_len (fsh->free_fifos); i++) + { + f = fsh->free_fifos[i]; + if (f == 0) + continue; + count = 0; + while (f) + { + f = f->next; + count++; + } + + s = format (s, "%U%-5u Kb: %u free", + format_white_space, indent + 2, + 1 << (i + max_log2 (FIFO_SEGMENT_MIN_FIFO_SIZE) - 10), + count); + } + return s; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/svm/svm_fifo_segment.h b/src/svm/svm_fifo_segment.h index 5cc4754a0a0..7c97e9b489f 100644 --- a/src/svm/svm_fifo_segment.h +++ b/src/svm/svm_fifo_segment.h @@ -118,7 +118,11 @@ void svm_fifo_segment_free_fifo (svm_fifo_segment_private_t * s, void svm_fifo_segment_init (u64 baseva, u32 timeout_in_seconds); u32 svm_fifo_segment_index (svm_fifo_segment_private_t * s); u32 svm_fifo_segment_num_fifos (svm_fifo_segment_private_t * fifo_segment); +u32 svm_fifo_segment_num_free_fifos (svm_fifo_segment_private_t * + fifo_segment, u32 fifo_size_in_bytes); + svm_fifo_segment_private_t *svm_fifo_segment_segments_pool (void); +format_function_t format_svm_fifo_segment; #endif /* __included_ssvm_fifo_segment_h__ */ diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index 7cf66ee35b2..c23e4c0237c 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -74,6 +74,11 @@ session_manager_add_segment_i (segment_manager_t * sm, u32 segment_size, } else { + u32 rx_fifo_size, tx_fifo_size, rx_rounded_data_size, + tx_rounded_data_size; + u32 approx_segment_count; + u64 approx_total_size; + ca->segment_name = "process-private-segment"; ca->segment_size = ~0; ca->rx_fifo_size = sm->properties->rx_fifo_size; @@ -82,6 +87,36 @@ session_manager_add_segment_i (segment_manager_t * sm, u32 segment_size, ca->private_segment_count = sm->properties->private_segment_count; ca->private_segment_size = sm->properties->private_segment_size; + /* Default to a small private segment */ + if (ca->private_segment_size == 0) + ca->private_segment_size = 128 << 20; + + /* Calculate space requirements */ + rx_rounded_data_size = (1 << (max_log2 (ca->rx_fifo_size))); + tx_rounded_data_size = (1 << (max_log2 (ca->tx_fifo_size))); + + rx_fifo_size = sizeof (svm_fifo_t) + rx_rounded_data_size; + tx_fifo_size = sizeof (svm_fifo_t) + tx_rounded_data_size; + + approx_total_size = (u64) ca->preallocated_fifo_pairs + * (rx_fifo_size + tx_fifo_size); + approx_segment_count = + (approx_total_size + + (ca->private_segment_size - 1)) / (u64) ca->private_segment_size; + + /* The user asked us to figure it out... */ + if (ca->private_segment_count == 0) + { + ca->private_segment_count = approx_segment_count; + } + /* Follow directions, but issue a warning */ + else if (approx_segment_count != ca->private_segment_count) + { + clib_warning + ("Honoring segment count %u, but calculated count was %u", + ca->private_segment_count, approx_segment_count); + } + if (svm_fifo_segment_create_process_private (ca)) clib_warning ("Failed to create process private segment"); @@ -503,7 +538,9 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, u8 show_segments = 0, verbose = 0, *name; uword address; u64 size; - u32 fifos; + u32 active_fifos; + u32 free_fifos; + mheap_t *heap_header; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) @@ -536,8 +573,8 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, segments = svm_fifo_segment_segments_pool (); vlib_cli_output (vm, "%d svm fifo segments allocated", pool_elts (segments)); - vlib_cli_output (vm, "%-20s%=12s%=12s%=15s", "Name", "Size (M)", - "Fifos", "Address"); + vlib_cli_output (vm, "%-20s%=12s%=16s%=16s%=16s", "Name", + "HeapSize (M)", "ActiveFifos", "FreeFifos", "Address"); /* *INDENT-OFF* */ pool_foreach (seg, segments, ({ @@ -557,9 +594,14 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, size = seg->ssvm.ssvm_size; name = seg->ssvm.sh->name; } - fifos = svm_fifo_segment_num_fifos (seg); - vlib_cli_output (vm, "%-20s%=12u%=12u%=15x", name, size << 20, fifos, + active_fifos = svm_fifo_segment_num_fifos (seg); + free_fifos = svm_fifo_segment_num_free_fifos (seg, ~0 /* size */); + vlib_cli_output (vm, "%-20v%=16llu%=16u%=16u%16llx", + name, size >> 20ULL, active_fifos, free_fifos, address); + if (verbose) + vlib_cli_output (vm, "%U", + format_svm_fifo_segment, seg, verbose); if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) vec_free (name); })); @@ -573,7 +615,7 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, VLIB_CLI_COMMAND (segment_manager_show_command, static) = { .path = "show segment-manager", - .short_help = "show segment-manager [segments]", + .short_help = "show segment-manager [segments][verbose]", .function = segment_manager_show_fn, }; /* *INDENT-ON* */ diff --git a/src/vnet/tcp/builtin_client.c b/src/vnet/tcp/builtin_client.c index 44b1f70e9df..94e6b4ae5d8 100644 --- a/src/vnet/tcp/builtin_client.c +++ b/src/vnet/tcp/builtin_client.c @@ -563,12 +563,14 @@ test_tcp_clients_command_fn (vlib_main_t * vm, else if (unformat (input, "private-segment-count %d", &tm->private_segment_count)) ; - else if (unformat (input, "private-segment-size %dm", &tmp)) - tm->private_segment_size = tmp << 20; - else if (unformat (input, "private-segment-size %dg", &tmp)) - tm->private_segment_size = tmp << 30; - else if (unformat (input, "private-segment-size %d", &tmp)) - tm->private_segment_size = tmp; + else if (unformat (input, "private-segment-size %U", + unformat_memory_size, &tmp)) + { + if (tmp >= 0x100000000ULL) + return clib_error_return + (0, "private segment size %lld (%llu) too large", tmp, tmp); + tm->private_segment_size = tmp; + } else if (unformat (input, "preallocate-fifos")) tm->prealloc_fifos = 1; else if (unformat (input, "preallocate-sessions")) diff --git a/src/vnet/tcp/builtin_proxy.c b/src/vnet/tcp/builtin_proxy.c index d8cfb11d315..91377e76726 100644 --- a/src/vnet/tcp/builtin_proxy.c +++ b/src/vnet/tcp/builtin_proxy.c @@ -523,7 +523,7 @@ proxy_server_create_command_fn (vlib_main_t * vm, unformat_input_t * input, { builtin_proxy_main_t *bpm = &builtin_proxy_main; int rv; - u32 tmp; + u64 tmp; bpm->fifo_size = 64 << 10; bpm->rcv_buffer_size = 1024; @@ -542,12 +542,14 @@ proxy_server_create_command_fn (vlib_main_t * vm, unformat_input_t * input, else if (unformat (input, "private-segment-count %d", &bpm->private_segment_count)) ; - else if (unformat (input, "private-segment-size %dm", &tmp)) - bpm->private_segment_size = tmp << 20; - else if (unformat (input, "private-segment-size %dg", &tmp)) - bpm->private_segment_size = tmp << 30; - else if (unformat (input, "private-segment-size %d", &tmp)) - bpm->private_segment_size = tmp; + else if (unformat (input, "private-segment-size %U", + unformat_memory_size, &tmp)) + { + if (tmp >= 0x100000000ULL) + return clib_error_return + (0, "private segment size %lld (%llu) too large", tmp, tmp); + bpm->private_segment_size = tmp; + } else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); diff --git a/src/vnet/tcp/builtin_server.c b/src/vnet/tcp/builtin_server.c index 295c189d869..93314529973 100644 --- a/src/vnet/tcp/builtin_server.c +++ b/src/vnet/tcp/builtin_server.c @@ -369,7 +369,7 @@ server_create_command_fn (vlib_main_t * vm, unformat_input_t * input, builtin_server_main_t *bsm = &builtin_server_main; u8 server_uri_set = 0; int rv; - u32 tmp; + u64 tmp; bsm->no_echo = 0; bsm->fifo_size = 64 << 10; @@ -392,12 +392,14 @@ server_create_command_fn (vlib_main_t * vm, unformat_input_t * input, else if (unformat (input, "private-segment-count %d", &bsm->private_segment_count)) ; - else if (unformat (input, "private-segment-size %dm", &tmp)) - bsm->private_segment_size = tmp << 20; - else if (unformat (input, "private-segment-size %dg", &tmp)) - bsm->private_segment_size = tmp << 30; - else if (unformat (input, "private-segment-size %d", &tmp)) - bsm->private_segment_size = tmp; + else if (unformat (input, "private-segment-size %U", + unformat_memory_size, &tmp)) + { + if (tmp >= 0x100000000ULL) + return clib_error_return + (0, "private segment size %lld (%llu) too large", tmp, tmp); + bsm->private_segment_size = tmp; + } else if (unformat (input, "uri %s", &bsm->server_uri)) server_uri_set = 1; else |