diff options
Diffstat (limited to 'vlib/vlib/node_cli.c')
-rw-r--r-- | vlib/vlib/node_cli.c | 414 |
1 files changed, 216 insertions, 198 deletions
diff --git a/vlib/vlib/node_cli.c b/vlib/vlib/node_cli.c index 13a1b91ef81..af9b47dd05d 100644 --- a/vlib/vlib/node_cli.c +++ b/vlib/vlib/node_cli.c @@ -41,21 +41,20 @@ #include <vlib/threads.h> static int -node_cmp (void * a1, void *a2) +node_cmp (void *a1, void *a2) { - vlib_node_t ** n1 = a1; - vlib_node_t ** n2 = a2; + vlib_node_t **n1 = a1; + vlib_node_t **n2 = a2; return vec_cmp (n1[0]->name, n2[0]->name); } static clib_error_t * show_node_graph (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, vlib_cli_command_t * cmd) { - vlib_node_main_t * nm = &vm->node_main; - vlib_node_t * n; + vlib_node_main_t *nm = &vm->node_main; + vlib_node_t *n; u32 node_index; vlib_cli_output (vm, "%U\n", format_vlib_node_graph, nm, 0); @@ -67,7 +66,7 @@ show_node_graph (vlib_main_t * vm, } else { - vlib_node_t ** nodes = vec_dup (nm->nodes); + vlib_node_t **nodes = vec_dup (nm->nodes); uword i; vec_sort_with_function (nodes, node_cmp); @@ -81,37 +80,42 @@ show_node_graph (vlib_main_t * vm, return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_node_graph_command, static) = { .path = "show vlib graph", .short_help = "Show packet processing node graph", .function = show_node_graph, }; +/* *INDENT-ON* */ -static u8 * format_vlib_node_stats (u8 * s, va_list * va) +static u8 * +format_vlib_node_stats (u8 * s, va_list * va) { - vlib_main_t * vm = va_arg (*va, vlib_main_t *); - vlib_node_t * n = va_arg (*va, vlib_node_t *); + vlib_main_t *vm = va_arg (*va, vlib_main_t *); + vlib_node_t *n = va_arg (*va, vlib_node_t *); int max = va_arg (*va, int); f64 v; - char * state; - u8 * ns; - u8 * misc_info = 0; + char *state; + u8 *ns; + u8 *misc_info = 0; u64 c, p, l, d; f64 x; - f64 maxc, maxcn; + f64 maxc, maxcn; u32 maxn; uword indent; - if (! n) + if (!n) { - if (max) - return format (s, - "%=30s%=17s%=16s%=16s%=16s%=16s", - "Name", "Max Node Clocks", "Vectors at Max", "Max Clocks", "Avg Clocks", "Avg Vectors/Call"); + if (max) + return format (s, + "%=30s%=17s%=16s%=16s%=16s%=16s", + "Name", "Max Node Clocks", "Vectors at Max", + "Max Clocks", "Avg Clocks", "Avg Vectors/Call"); else - return format (s, - "%=30s%=12s%=16s%=16s%=16s%=16s%=16s", - "Name", "State", "Calls", "Vectors", "Suspends", "Clocks", "Vectors/Call"); + return format (s, + "%=30s%=12s%=16s%=16s%=16s%=16s%=16s", + "Name", "State", "Calls", "Vectors", "Suspends", + "Clocks", "Vectors/Call"); } indent = format_get_indent (s); @@ -120,11 +124,11 @@ static u8 * format_vlib_node_stats (u8 * s, va_list * va) c = n->stats_total.calls - n->stats_last_clear.calls; p = n->stats_total.vectors - n->stats_last_clear.vectors; d = n->stats_total.suspends - n->stats_last_clear.suspends; - maxc = (f64)n->stats_total.max_clock; + maxc = (f64) n->stats_total.max_clock; maxn = n->stats_total.max_clock_n; - if (n->stats_total.max_clock_n) - maxcn = (f64)n->stats_total.max_clock / (f64)maxn; - else + if (n->stats_total.max_clock_n) + maxcn = (f64) n->stats_total.max_clock / (f64) maxn; + else maxcn = 0.0; /* Clocks per packet, per call or per suspend. */ @@ -135,27 +139,27 @@ static u8 * format_vlib_node_stats (u8 * s, va_list * va) x = (f64) l / (f64) c; else if (d > 0) x = (f64) l / (f64) d; - + if (c > 0) - v = (double)p / (double)c; + v = (double) p / (double) c; else v = 0; state = "active"; if (n->type == VLIB_NODE_TYPE_PROCESS) { - vlib_process_t * p = vlib_get_process_from_node (vm, n); + vlib_process_t *p = vlib_get_process_from_node (vm, n); /* Show processes with events pending. This helps spot bugs where events are not - being handled. */ - if (! clib_bitmap_is_zero (p->non_empty_event_type_bitmap)) + being handled. */ + if (!clib_bitmap_is_zero (p->non_empty_event_type_bitmap)) misc_info = format (misc_info, "events pending, "); switch (p->flags & (VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK | VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT)) { default: - if (! (p->flags & VLIB_PROCESS_IS_RUNNING)) + if (!(p->flags & VLIB_PROCESS_IS_RUNNING)) state = "done"; break; @@ -167,12 +171,12 @@ static u8 * format_vlib_node_stats (u8 * s, va_list * va) state = "event wait"; break; - case (VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT - | VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK): - state = "any wait"; + case (VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT | VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK): + state = + "any wait"; break; } - } + } else if (n->type != VLIB_NODE_TYPE_INTERNAL) { state = "polling"; @@ -186,10 +190,10 @@ static u8 * format_vlib_node_stats (u8 * s, va_list * va) if (max) s = format (s, "%-30v%=17.2e%=16d%=16.2e%=16.2e%=16.2e", - ns, maxc, maxn, maxcn, x, v); + ns, maxc, maxn, maxcn, x, v); else s = format (s, "%-30v%=12s%16Ld%16Ld%16Ld%16.2e%16.2f", ns, state, - c, p, d, x, v); + c, p, d, x, v); if (ns != n->name) vec_free (ns); @@ -205,16 +209,15 @@ static u8 * format_vlib_node_stats (u8 * s, va_list * va) static clib_error_t * show_node_runtime (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, vlib_cli_command_t * cmd) { - vlib_node_main_t * nm = &vm->node_main; - vlib_node_t * n; + vlib_node_main_t *nm = &vm->node_main; + vlib_node_t *n; f64 time_now; u32 node_index; - vlib_node_t *** node_dups = 0; - f64 * vectors_per_main_loop = 0; - f64 * last_vector_length_per_node = 0; + vlib_node_t ***node_dups = 0; + f64 *vectors_per_main_loop = 0; + f64 *last_vector_length_per_node = 0; time_now = vlib_time_now (vm); @@ -227,7 +230,7 @@ show_node_runtime (vlib_main_t * vm, } else { - vlib_node_t ** nodes; + vlib_node_t **nodes; uword i, j; f64 dt; u64 n_input, n_output, n_drop, n_punt; @@ -235,143 +238,144 @@ show_node_runtime (vlib_main_t * vm, u64 n_clocks, l, v, c, d; int brief = 1; int max = 0; - vlib_main_t ** stat_vms = 0, *stat_vm; + vlib_main_t **stat_vms = 0, *stat_vm; /* Suppress nodes with zero calls since last clear */ if (unformat (input, "brief") || unformat (input, "b")) - brief = 1; - if (unformat (input, "verbose") || unformat(input, "v")) - brief = 0; - if (unformat (input, "max") || unformat(input, "m")) - max = 1; - - if (vec_len(vlib_mains) == 0) - vec_add1 (stat_vms, vm); + brief = 1; + if (unformat (input, "verbose") || unformat (input, "v")) + brief = 0; + if (unformat (input, "max") || unformat (input, "m")) + max = 1; + + if (vec_len (vlib_mains) == 0) + vec_add1 (stat_vms, vm); else - { - for (i = 0; i < vec_len (vlib_mains); i++) - { - stat_vm = vlib_mains[i]; - if (stat_vm) - vec_add1 (stat_vms, stat_vm); - } - } - - /* + { + for (i = 0; i < vec_len (vlib_mains); i++) + { + stat_vm = vlib_mains[i]; + if (stat_vm) + vec_add1 (stat_vms, stat_vm); + } + } + + /* * Barrier sync across stats scraping. * Otherwise, the counts will be grossly inaccurate. */ - vlib_worker_thread_barrier_sync(vm); + vlib_worker_thread_barrier_sync (vm); for (j = 0; j < vec_len (stat_vms); j++) - { - stat_vm = stat_vms[j]; - nm = &stat_vm->node_main; - - for (i = 0; i < vec_len (nm->nodes); i++) - { - n = nm->nodes[i]; - vlib_node_sync_stats (stat_vm, n); - } - - nodes = vec_dup (nm->nodes); - - vec_add1(node_dups, nodes); - vec_add1 (vectors_per_main_loop, - vlib_last_vectors_per_main_loop_as_f64 (stat_vm)); - vec_add1 (last_vector_length_per_node, - vlib_last_vector_length_per_node (stat_vm)); - } - vlib_worker_thread_barrier_release(vm); + { + stat_vm = stat_vms[j]; + nm = &stat_vm->node_main; + + for (i = 0; i < vec_len (nm->nodes); i++) + { + n = nm->nodes[i]; + vlib_node_sync_stats (stat_vm, n); + } + + nodes = vec_dup (nm->nodes); + + vec_add1 (node_dups, nodes); + vec_add1 (vectors_per_main_loop, + vlib_last_vectors_per_main_loop_as_f64 (stat_vm)); + vec_add1 (last_vector_length_per_node, + vlib_last_vector_length_per_node (stat_vm)); + } + vlib_worker_thread_barrier_release (vm); for (j = 0; j < vec_len (stat_vms); j++) - { - stat_vm = stat_vms[j]; - nodes = node_dups[j]; - - vec_sort_with_function (nodes, node_cmp); - - n_input = n_output = n_drop = n_punt = n_clocks = 0; - n_internal_vectors = n_internal_calls = 0; - for (i = 0; i < vec_len (nodes); i++) - { - n = nodes[i]; - - l = n->stats_total.clocks - n->stats_last_clear.clocks; - n_clocks += l; - - v = n->stats_total.vectors - n->stats_last_clear.vectors; - c = n->stats_total.calls - n->stats_last_clear.calls; - - switch (n->type) - { - default: - continue; - - case VLIB_NODE_TYPE_INTERNAL: - n_output += (n->flags & VLIB_NODE_FLAG_IS_OUTPUT) ? v : 0; - n_drop += (n->flags & VLIB_NODE_FLAG_IS_DROP) ? v : 0; - n_punt += (n->flags & VLIB_NODE_FLAG_IS_PUNT) ? v : 0; - if (! (n->flags & VLIB_NODE_FLAG_IS_OUTPUT)) - { - n_internal_vectors += v; - n_internal_calls += c; - } - if (n->flags & VLIB_NODE_FLAG_IS_HANDOFF) - n_input += v; - break; - - case VLIB_NODE_TYPE_INPUT: - n_input += v; - break; - } - } - - if (vec_len (vlib_mains)) - { - vlib_worker_thread_t *w = vlib_worker_threads + j; - if (j > 0) - vlib_cli_output (vm, "---------------"); - - if ( w->dpdk_lcore_id > -1) - vlib_cli_output (vm, "Thread %d %s (lcore %u)", j, w->name, - w->dpdk_lcore_id); - else - vlib_cli_output (vm, "Thread %d %s", j, - w->name); - } - - dt = time_now - nm->time_last_runtime_stats_clear; - vlib_cli_output - (vm, - "Time %.1f, average vectors/node %.2f, last %d main loops %.2f per node %.2f" - "\n vector rates in %.4e, out %.4e, drop %.4e, punt %.4e", - dt, - (n_internal_calls > 0 - ? (f64) n_internal_vectors / (f64) n_internal_calls - : 0), - 1 << VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE, - vectors_per_main_loop [j], - last_vector_length_per_node [j], - (f64) n_input / dt, - (f64) n_output / dt, - (f64) n_drop / dt, - (f64) n_punt / dt); - - vlib_cli_output (vm, "%U", format_vlib_node_stats, stat_vm, 0, max); - for (i = 0; i < vec_len (nodes); i++) - { - c = nodes[i]->stats_total.calls - nodes[i]->stats_last_clear.calls; - d = nodes[i]->stats_total.suspends - nodes[i]->stats_last_clear.suspends; - if (c || d || ! brief) - { - vlib_cli_output (vm, "%U", format_vlib_node_stats, stat_vm, - nodes[i], max); - } - } - vec_free (nodes); - } + { + stat_vm = stat_vms[j]; + nodes = node_dups[j]; + + vec_sort_with_function (nodes, node_cmp); + + n_input = n_output = n_drop = n_punt = n_clocks = 0; + n_internal_vectors = n_internal_calls = 0; + for (i = 0; i < vec_len (nodes); i++) + { + n = nodes[i]; + + l = n->stats_total.clocks - n->stats_last_clear.clocks; + n_clocks += l; + + v = n->stats_total.vectors - n->stats_last_clear.vectors; + c = n->stats_total.calls - n->stats_last_clear.calls; + + switch (n->type) + { + default: + continue; + + case VLIB_NODE_TYPE_INTERNAL: + n_output += (n->flags & VLIB_NODE_FLAG_IS_OUTPUT) ? v : 0; + n_drop += (n->flags & VLIB_NODE_FLAG_IS_DROP) ? v : 0; + n_punt += (n->flags & VLIB_NODE_FLAG_IS_PUNT) ? v : 0; + if (!(n->flags & VLIB_NODE_FLAG_IS_OUTPUT)) + { + n_internal_vectors += v; + n_internal_calls += c; + } + if (n->flags & VLIB_NODE_FLAG_IS_HANDOFF) + n_input += v; + break; + + case VLIB_NODE_TYPE_INPUT: + n_input += v; + break; + } + } + + if (vec_len (vlib_mains)) + { + vlib_worker_thread_t *w = vlib_worker_threads + j; + if (j > 0) + vlib_cli_output (vm, "---------------"); + + if (w->dpdk_lcore_id > -1) + vlib_cli_output (vm, "Thread %d %s (lcore %u)", j, w->name, + w->dpdk_lcore_id); + else + vlib_cli_output (vm, "Thread %d %s", j, w->name); + } + + dt = time_now - nm->time_last_runtime_stats_clear; + vlib_cli_output + (vm, + "Time %.1f, average vectors/node %.2f, last %d main loops %.2f per node %.2f" + "\n vector rates in %.4e, out %.4e, drop %.4e, punt %.4e", + dt, + (n_internal_calls > 0 + ? (f64) n_internal_vectors / (f64) n_internal_calls + : 0), + 1 << VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE, + vectors_per_main_loop[j], + last_vector_length_per_node[j], + (f64) n_input / dt, + (f64) n_output / dt, (f64) n_drop / dt, (f64) n_punt / dt); + + vlib_cli_output (vm, "%U", format_vlib_node_stats, stat_vm, 0, max); + for (i = 0; i < vec_len (nodes); i++) + { + c = + nodes[i]->stats_total.calls - + nodes[i]->stats_last_clear.calls; + d = + nodes[i]->stats_total.suspends - + nodes[i]->stats_last_clear.suspends; + if (c || d || !brief) + { + vlib_cli_output (vm, "%U", format_vlib_node_stats, stat_vm, + nodes[i], max); + } + } + vec_free (nodes); + } vec_free (stat_vms); vec_free (node_dups); vec_free (vectors_per_main_loop); @@ -381,68 +385,82 @@ show_node_runtime (vlib_main_t * vm, return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (show_node_runtime_command, static) = { .path = "show runtime", .short_help = "Show packet processing runtime", .function = show_node_runtime, .is_mp_safe = 1, }; +/* *INDENT-ON* */ static clib_error_t * clear_node_runtime (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) + unformat_input_t * input, vlib_cli_command_t * cmd) { - vlib_node_main_t * nm; - vlib_node_t * n; + vlib_node_main_t *nm; + vlib_node_t *n; int i, j; - vlib_main_t ** stat_vms = 0, *stat_vm; - vlib_node_runtime_t * r; + vlib_main_t **stat_vms = 0, *stat_vm; + vlib_node_runtime_t *r; - if (vec_len(vlib_mains) == 0) + if (vec_len (vlib_mains) == 0) vec_add1 (stat_vms, vm); else { for (i = 0; i < vec_len (vlib_mains); i++) - { - stat_vm = vlib_mains[i]; - if (stat_vm) - vec_add1 (stat_vms, stat_vm); - } + { + stat_vm = vlib_mains[i]; + if (stat_vm) + vec_add1 (stat_vms, stat_vm); + } } - - vlib_worker_thread_barrier_sync(vm); + + vlib_worker_thread_barrier_sync (vm); for (j = 0; j < vec_len (stat_vms); j++) { stat_vm = stat_vms[j]; nm = &stat_vm->node_main; - + for (i = 0; i < vec_len (nm->nodes); i++) - { - n = nm->nodes[i]; - vlib_node_sync_stats (stat_vm, n); - n->stats_last_clear = n->stats_total; - - r = vlib_node_get_runtime (stat_vm, n->index); - r->max_clock = 0; - } + { + n = nm->nodes[i]; + vlib_node_sync_stats (stat_vm, n); + n->stats_last_clear = n->stats_total; + + r = vlib_node_get_runtime (stat_vm, n->index); + r->max_clock = 0; + } /* Note: input/output rates computed using vlib_global_main */ nm->time_last_runtime_stats_clear = vlib_time_now (vm); } - vlib_worker_thread_barrier_release(vm); - + vlib_worker_thread_barrier_release (vm); + vec_free (stat_vms); return 0; } +/* *INDENT-OFF* */ VLIB_CLI_COMMAND (clear_node_runtime_command, static) = { .path = "clear runtime", .short_help = "Clear packet processing runtime statistics", .function = clear_node_runtime, }; +/* *INDENT-ON* */ /* Dummy function to get us linked in. */ -void vlib_node_cli_reference (void) {} +void +vlib_node_cli_reference (void) +{ +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |