X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Ftrace.c;h=156378af8e33d225cbf920954b221fa97acaee88;hb=e700df8eb4f640762d5eced6623bbc2473ad0095;hp=530598d349dd2b432198f91866472a319b8ef1b5;hpb=7ca5aaac10e95306f74ea4afd52110dd46aa0381;p=vpp.git diff --git a/src/vlib/trace.c b/src/vlib/trace.c index 530598d349d..156378af8e3 100644 --- a/src/vlib/trace.c +++ b/src/vlib/trace.c @@ -39,8 +39,9 @@ #include #include +#include -u8 *vnet_trace_dummy; +u8 *vnet_trace_placeholder; /* Helper function for nodes which only trace buffer data. */ void @@ -110,7 +111,7 @@ vlib_trace_frame_buffers_only (vlib_main_t * vm, } /* Free up all trace buffer memory. */ -always_inline void +void clear_trace_buffer (void) { int i; @@ -122,6 +123,12 @@ clear_trace_buffer (void) tm = &this_vlib_main->trace_main; tm->trace_enable = 0; + vec_free (tm->nodes); + })); + + foreach_vlib_main ( + ({ + tm = &this_vlib_main->trace_main; for (i = 0; i < vec_len (tm->trace_buffer_pool); i++) if (! pool_is_free_index (tm->trace_buffer_pool, i)) @@ -175,8 +182,8 @@ VLIB_CLI_COMMAND (trace_cli_command,static) = { }; /* *INDENT-ON* */ -static int -trace_cmp (void *a1, void *a2) +int +trace_time_cmp (void *a1, void *a2) { vlib_trace_header_t **t1 = a1; vlib_trace_header_t **t2 = a2; @@ -195,6 +202,15 @@ filter_accept (vlib_trace_main_t * tm, vlib_trace_header_t * h) if (tm->filter_flag == 0) return 1; + /* + * When capturing a post-mortem dispatch trace, + * toss all existing traces once per dispatch cycle. + * So we can trace 4 billion pkts without running out of + * memory... + */ + if (tm->filter_flag == FILTER_FLAG_POST_MORTEM) + return 0; + if (tm->filter_flag == FILTER_FLAG_INCLUDE) { while (h < e) @@ -243,15 +259,15 @@ trace_apply_filter (vlib_main_t * vm) */ n_accepted = 0; /* *INDENT-OFF* */ - pool_foreach (h, tm->trace_buffer_pool, - ({ + pool_foreach (h, tm->trace_buffer_pool) + { accept = filter_accept(tm, h[0]); if ((n_accepted == tm->filter_count) || !accept) vec_add1 (traces_to_remove, h); else n_accepted++; - })); + } /* *INDENT-ON* */ /* remove all traces that we don't want to keep */ @@ -304,10 +320,10 @@ cli_show_trace_buffer (vlib_main_t * vm, trace_apply_filter(this_vlib_main); traces = 0; - pool_foreach (h, tm->trace_buffer_pool, - ({ + pool_foreach (h, tm->trace_buffer_pool) + { vec_add1 (traces, h[0]); - })); + } if (vec_len (traces) == 0) { @@ -316,7 +332,7 @@ cli_show_trace_buffer (vlib_main_t * vm, } /* Sort them by increasing time. */ - vec_sort_with_function (traces, trace_cmp); + vec_sort_with_function (traces, trace_time_cmp); for (i = 0; i < vec_len (traces); i++) { @@ -351,23 +367,77 @@ VLIB_CLI_COMMAND (show_trace_cli,static) = { }; /* *INDENT-ON* */ +int vlib_enable_disable_pkt_trace_filter (int enable) __attribute__ ((weak)); + +int +vlib_enable_disable_pkt_trace_filter (int enable) +{ + return 0; +} + +void +vlib_trace_stop_and_clear (void) +{ + vlib_enable_disable_pkt_trace_filter (0); /* disble tracing */ + clear_trace_buffer (); +} + + +void +trace_update_capture_options (u32 add, u32 node_index, u32 filter, u8 verbose) +{ + vlib_trace_main_t *tm; + vlib_trace_node_t *tn; + + if (add == ~0) + add = 50; + + /* *INDENT-OFF* */ + foreach_vlib_main (( + { + tm = &this_vlib_main->trace_main; + tm->verbose = verbose; + vec_validate (tm->nodes, node_index); + tn = tm->nodes + node_index; + + /* + * Adding 0 makes no real sense, and there wa no other way + * to explicilty zero-out the limits and count, so make + * an "add 0" request really be "set to 0". + */ + if (add == 0) + tn->limit = tn->count = 0; + else + tn->limit += add; + })); + + foreach_vlib_main (( + { + tm = &this_vlib_main->trace_main; + tm->trace_enable = 1; + })); + /* *INDENT-ON* */ + + vlib_enable_disable_pkt_trace_filter (! !filter); +} + static clib_error_t * cli_add_trace_buffer (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; - vlib_trace_main_t *tm; vlib_node_t *node; - vlib_trace_node_t *tn; u32 node_index, add; u8 verbose = 0; + int filter = 0; clib_error_t *error = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; - if (vnet_trace_dummy == 0) - vec_validate_aligned (vnet_trace_dummy, 2048, CLIB_CACHE_LINE_BYTES); + if (vnet_trace_placeholder == 0) + vec_validate_aligned (vnet_trace_placeholder, 2048, + CLIB_CACHE_LINE_BYTES); while (unformat_check_input (line_input) != (uword) UNFORMAT_END_OF_INPUT) { @@ -376,6 +446,8 @@ cli_add_trace_buffer (vlib_main_t * vm, ; else if (unformat (line_input, "verbose")) verbose = 1; + else if (unformat (line_input, "filter")) + filter = 1; else { error = clib_error_create ("expected NODE COUNT, got `%U'", @@ -395,17 +467,14 @@ cli_add_trace_buffer (vlib_main_t * vm, goto done; } - /* *INDENT-OFF* */ - foreach_vlib_main (( + u32 filter_table = classify_get_trace_chain (); + if (filter && filter_table == ~0) { - tm = &this_vlib_main->trace_main; - tm->verbose = verbose; - vec_validate (tm->nodes, node_index); - tn = tm->nodes + node_index; - tn->limit += add; - tm->trace_enable = 1; - })); - /* *INDENT-ON* */ + error = clib_error_create ("No packet trace filter configured..."); + goto done; + } + + trace_update_capture_options (add, node_index, filter, verbose); done: unformat_free (line_input); @@ -416,12 +485,11 @@ done: /* *INDENT-OFF* */ VLIB_CLI_COMMAND (add_trace_cli,static) = { .path = "trace add", - .short_help = "Trace given number of packets", + .short_help = "trace add [filter] [verbose]", .function = cli_add_trace_buffer, }; /* *INDENT-ON* */ - /* * Configure a filter for packet traces. * @@ -459,11 +527,35 @@ VLIB_CLI_COMMAND (add_trace_cli,static) = { * criteria (e.g. input sw_if_index, mac address) but for now just checks if * a specified node is in the trace or not in the trace. */ + +void +trace_filter_set (u32 node_index, u32 flag, u32 count) +{ + /* *INDENT-OFF* */ + foreach_vlib_main ( + ({ + vlib_trace_main_t *tm; + + tm = &this_vlib_main->trace_main; + tm->filter_node_index = node_index; + tm->filter_flag = flag; + tm->filter_count = count; + + /* + * Clear the trace limits to stop any in-progress tracing + * Prevents runaway trace allocations when the filter changes + * (or is removed) + */ + vec_free (tm->nodes); + })); + /* *INDENT-ON* */ +} + + static clib_error_t * cli_filter_trace (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - vlib_trace_main_t *tm = &vm->trace_main; u32 filter_node_index; u32 filter_flag; u32 filter_count; @@ -491,22 +583,7 @@ cli_filter_trace (vlib_main_t * vm, ("expected 'include NODE COUNT' or 'exclude NODE COUNT' or 'none', got `%U'", format_unformat_error, input); - /* *INDENT-OFF* */ - foreach_vlib_main ( - ({ - tm = &this_vlib_main->trace_main; - tm->filter_node_index = filter_node_index; - tm->filter_flag = filter_flag; - tm->filter_count = filter_count; - - /* - * Clear the trace limits to stop any in-progress tracing - * Prevents runaway trace allocations when the filter changes - * (or is removed) - */ - vec_free (tm->nodes); - })); - /* *INDENT-ON* */ + trace_filter_set (filter_node_index, filter_flag, filter_count); return 0; } @@ -514,7 +591,7 @@ cli_filter_trace (vlib_main_t * vm, /* *INDENT-OFF* */ VLIB_CLI_COMMAND (filter_trace_cli,static) = { .path = "trace filter", - .short_help = "filter trace output - include NODE COUNT | exclude NODE COUNT | none", + .short_help = "trace filter none | [include|exclude] NODE COUNT", .function = cli_filter_trace, }; /* *INDENT-ON* */ @@ -523,7 +600,7 @@ static clib_error_t * cli_clear_trace_buffer (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - clear_trace_buffer (); + vlib_trace_stop_and_clear (); return 0; } @@ -535,12 +612,33 @@ VLIB_CLI_COMMAND (clear_trace_cli,static) = { }; /* *INDENT-ON* */ -/* Dummy function to get us linked in. */ +/* Placeholder function to get us linked in. */ void vlib_trace_cli_reference (void) { } +int +vnet_is_packet_traced (vlib_buffer_t * b, + u32 classify_table_index, int func) +__attribute__ ((weak)); + +int +vnet_is_packet_traced (vlib_buffer_t * b, u32 classify_table_index, int func) +{ + clib_warning ("BUG: STUB called"); + return 1; +} + +void * +vlib_add_trace (vlib_main_t * vm, + vlib_node_runtime_t * r, vlib_buffer_t * b, u32 n_data_bytes) +{ + return vlib_add_trace_inline (vm, r, b, n_data_bytes); +} + + + /* * fd.io coding-style-patch-verification: ON *