X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fmain.c;h=dc11128476b711a9889a3ba9cfa120d63e0c165b;hb=a8df85ce1fe957efa8301bd5b5ac3c03737d31f1;hp=0786465e0e4e7dfeb34be323fafb66c7615237a7;hpb=58b2eb1af562c292feb6d3cdce4656746e61da75;p=vpp.git diff --git a/src/vlib/main.c b/src/vlib/main.c index 0786465e0e4..dc11128476b 100644 --- a/src/vlib/main.c +++ b/src/vlib/main.c @@ -52,8 +52,6 @@ CJ_GLOBAL_LOG_PROTOTYPE; speculative vector enqueues which overflow vector data in next frame. */ #define VLIB_FRAME_SIZE_ALLOC (VLIB_FRAME_SIZE + 4) -u32 wraps; - always_inline u32 vlib_frame_bytes (u32 n_scalar_bytes, u32 n_vector_bytes) { @@ -1376,6 +1374,12 @@ dispatch_pending_node (vlib_main_t * vm, uword pending_frame_index, VLIB_NODE_TYPE_INTERNAL, VLIB_NODE_STATE_POLLING, f, last_time_stamp); + /* Internal node vector-rate accounting, for summary stats */ + vm->internal_node_vectors += f->n_vectors; + vm->internal_node_calls++; + vm->internal_node_last_vectors_per_main_loop = + (f->n_vectors > vm->internal_node_last_vectors_per_main_loop) ? + f->n_vectors : vm->internal_node_last_vectors_per_main_loop; f->frame_flags &= ~(VLIB_FRAME_PENDING | VLIB_FRAME_NO_APPEND); @@ -1915,7 +1919,6 @@ vlib_main_or_worker_loop (vlib_main_t * vm, int is_main) } } vlib_increment_main_loop_counter (vm); - /* Record time stamp in case there are no enabled nodes and above calls do not update time stamp. */ cpu_time_now = clib_cpu_time_now (); @@ -2159,169 +2162,203 @@ done: return 0; } -static inline clib_error_t * -pcap_dispatch_trace_command_internal (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd, int rx_tx) +int +vlib_pcap_dispatch_trace_configure (vlib_pcap_dispatch_trace_args_t * a) { - unformat_input_t _line_input, *line_input = &_line_input; + vlib_main_t *vm = vlib_get_main (); pcap_main_t *pm = &vm->dispatch_pcap_main; - u8 *filename = 0; - u32 max = 1000; - int enabled = 0; - int is_error = 0; - clib_error_t *error = 0; - u32 node_index, add; vlib_trace_main_t *tm; vlib_trace_node_t *tn; - /* Get a line of input. */ - if (!unformat_user (input, unformat_line_input, line_input)) - return 0; - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + if (a->status) { - if (unformat (line_input, "on")) + if (vm->dispatch_pcap_enable) { - if (vm->dispatch_pcap_enable == 0) - { - enabled = 1; - } - else - { - vlib_cli_output (vm, "pcap dispatch capture already on..."); - is_error = 1; - break; - } - } - else if (unformat (line_input, "off")) - { - if (vm->dispatch_pcap_enable) - { - vlib_cli_output - (vm, "captured %d pkts...", pm->n_packets_captured); - if (pm->n_packets_captured) - { - pm->n_packets_to_capture = pm->n_packets_captured; - error = pcap_write (pm); - if (error) - clib_error_report (error); - else - vlib_cli_output (vm, "saved to %s...", pm->file_name); - } - vm->dispatch_pcap_enable = 0; - } - else - { - vlib_cli_output (vm, "pcap tx capture already off..."); - is_error = 1; - break; - } - } - else if (unformat (line_input, "max %d", &max)) - { - if (vm->dispatch_pcap_enable) + int i; + vlib_cli_output + (vm, "pcap dispatch capture enabled: %d of %d pkts...", + pm->n_packets_captured, pm->n_packets_to_capture); + vlib_cli_output (vm, "capture to file %s", pm->file_name); + + for (i = 0; i < vec_len (vm->dispatch_buffer_trace_nodes); i++) { - vlib_cli_output - (vm, - "can't change max value while pcap tx capture active..."); - is_error = 1; - break; + vlib_cli_output (vm, + "Buffer trace of %d pkts from %U enabled...", + a->buffer_traces_to_capture, + format_vlib_node_name, vm, + vm->dispatch_buffer_trace_nodes[i]); } - pm->n_packets_to_capture = max; } else - if (unformat - (line_input, "file %U", unformat_vlib_tmpfile, &filename)) - { - if (vm->dispatch_pcap_enable) - { - vlib_cli_output - (vm, "can't change file while pcap tx capture active..."); - is_error = 1; - break; - } - } - else if (unformat (line_input, "status")) - { - if (vm->dispatch_pcap_enable) - { - vlib_cli_output - (vm, "pcap dispatch capture is on: %d of %d pkts...", - pm->n_packets_captured, pm->n_packets_to_capture); - vlib_cli_output (vm, "Capture to file %s", pm->file_name); - } - else - { - vlib_cli_output (vm, "pcap dispatch capture is off..."); - } - break; - } - else if (unformat (line_input, "buffer-trace %U %d", - unformat_vlib_node, vm, &node_index, &add)) - { - if (vnet_trace_dummy == 0) - vec_validate_aligned (vnet_trace_dummy, 2048, - CLIB_CACHE_LINE_BYTES); - vlib_cli_output (vm, "Buffer tracing of %d pkts from %U enabled...", - add, format_vlib_node_name, vm, node_index); + vlib_cli_output (vm, "pcap dispatch capture disabled"); + return 0; + } - /* *INDENT-OFF* */ - foreach_vlib_main (( - { - tm = &this_vlib_main->trace_main; - tm->verbose = 0; /* not sure this ever did anything... */ - vec_validate (tm->nodes, node_index); - tn = tm->nodes + node_index; - tn->limit += add; - tm->trace_enable = 1; - })); - /* *INDENT-ON* */ - } + /* Consistency checks */ - else - { - error = clib_error_return (0, "unknown input `%U'", - format_unformat_error, line_input); - is_error = 1; - break; - } + /* Enable w/ capture already enabled not allowed */ + if (vm->dispatch_pcap_enable && a->enable) + return -7; /* VNET_API_ERROR_INVALID_VALUE */ + + /* Disable capture with capture already disabled, not interesting */ + if (vm->dispatch_pcap_enable == 0 && a->enable == 0) + return -81; /* VNET_API_ERROR_VALUE_EXIST */ + + /* Change number of packets to capture while capturing */ + if (vm->dispatch_pcap_enable && a->enable + && (pm->n_packets_to_capture != a->packets_to_capture)) + return -8; /* VNET_API_ERROR_INVALID_VALUE_2 */ + + /* Independent of enable/disable, to allow buffer trace multi nodes */ + if (a->buffer_trace_node_index != ~0) + { + /* *INDENT-OFF* */ + foreach_vlib_main (( + { + tm = &this_vlib_main->trace_main; + tm->verbose = 0; /* not sure this ever did anything... */ + vec_validate (tm->nodes, a->buffer_trace_node_index); + tn = tm->nodes + a->buffer_trace_node_index; + tn->limit += a->buffer_traces_to_capture; + tm->trace_enable = 1; + })); + /* *INDENT-ON* */ + vec_add1 (vm->dispatch_buffer_trace_nodes, a->buffer_trace_node_index); } - unformat_free (line_input); - if (is_error == 0) + if (a->enable) { - /* Clean up from previous run */ + /* Clean up from previous run, if any */ vec_free (pm->file_name); vec_free (pm->pcap_data); - memset (pm, 0, sizeof (*pm)); - pm->n_packets_to_capture = max; - if (enabled) + vec_validate_aligned (vnet_trace_dummy, 2048, CLIB_CACHE_LINE_BYTES); + if (pm->lock == 0) + clib_spinlock_init (&(pm->lock)); + + if (a->filename == 0) + a->filename = format (0, "/tmp/dispatch.pcap%c", 0); + + pm->file_name = (char *) a->filename; + pm->n_packets_captured = 0; + pm->packet_type = PCAP_PACKET_TYPE_vpp; + vm->dispatch_pcap_enable = 1; + pm->n_packets_to_capture = a->packets_to_capture; + } + else + { + vm->dispatch_pcap_enable = 0; + vec_reset_length (vm->dispatch_buffer_trace_nodes); + if (pm->n_packets_captured) { - if (filename == 0) - filename = format (0, "/tmp/dispatch.pcap%c", 0); - - pm->file_name = (char *) filename; - pm->n_packets_captured = 0; - pm->packet_type = PCAP_PACKET_TYPE_vpp; - if (pm->lock == 0) - clib_spinlock_init (&(pm->lock)); - vm->dispatch_pcap_enable = 1; - vlib_cli_output (vm, "pcap dispatch capture on..."); + clib_error_t *error; + pm->n_packets_to_capture = pm->n_packets_captured; + vlib_cli_output (vm, "Write %d packets to %s, and stop capture...", + pm->n_packets_captured, pm->file_name); + error = pcap_write (pm); + if (pm->flags & PCAP_MAIN_INIT_DONE) + pcap_close (pm); + /* Report I/O errors... */ + if (error) + { + clib_error_report (error); + return -11; /* VNET_API_ERROR_SYSCALL_ERROR_1 */ + } + return 0; } + else + return -6; /* VNET_API_ERROR_NO_SUCH_ENTRY */ } - return error; + return 0; } static clib_error_t * -pcap_dispatch_trace_command_fn (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) +dispatch_trace_command_fn (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) { - return pcap_dispatch_trace_command_internal (vm, input, cmd, VLIB_RX); + unformat_input_t _line_input, *line_input = &_line_input; + vlib_pcap_dispatch_trace_args_t _a, *a = &_a; + u8 *filename = 0; + u32 max = 1000; + int rv; + int enable = 0; + int status = 0; + u32 node_index = ~0, buffer_traces_to_capture = 100; + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "on %=", &enable, 1)) + ; + else if (unformat (line_input, "enable %=", &enable, 1)) + ; + else if (unformat (line_input, "off %=", &enable, 0)) + ; + else if (unformat (line_input, "disable %=", &enable, 0)) + ; + else if (unformat (line_input, "max %d", &max)) + ; + else if (unformat (line_input, "packets-to-capture %d", &max)) + ; + else if (unformat (line_input, "file %U", unformat_vlib_tmpfile, + &filename)) + ; + else if (unformat (line_input, "status %=", &status, 1)) + ; + else if (unformat (line_input, "buffer-trace %U %d", + unformat_vlib_node, vm, &node_index, + &buffer_traces_to_capture)) + ; + else + { + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + } + } + + unformat_free (line_input); + + /* no need for memset (a, 0, sizeof (*a)), set all fields here. */ + a->filename = filename; + a->enable = enable; + a->status = status; + a->packets_to_capture = max; + a->buffer_trace_node_index = node_index; + a->buffer_traces_to_capture = buffer_traces_to_capture; + + rv = vlib_pcap_dispatch_trace_configure (a); + + switch (rv) + { + case 0: + break; + + case -7: + return clib_error_return (0, "dispatch trace already enabled..."); + + case -81: + return clib_error_return (0, "dispatch trace already disabled..."); + + case -8: + return clib_error_return + (0, "can't change number of records to capture while tracing..."); + + case -11: + return clib_error_return (0, "I/O writing trace capture..."); + + case -6: + return clib_error_return (0, "No packets captured..."); + + default: + vlib_cli_output (vm, "WARNING: trace configure returned %d", rv); + break; + } + return 0; } /*? @@ -2381,7 +2418,7 @@ VLIB_CLI_COMMAND (pcap_dispatch_trace_command, static) = { .short_help = "pcap dispatch trace [on|off] [max ] [file ] [status]\n" " [buffer-trace ]", - .function = pcap_dispatch_trace_command_fn, + .function = dispatch_trace_command_fn, }; /* *INDENT-ON* */