return p;
}
-static vlib_frame_size_t *
+static inline vlib_frame_size_t *
get_frame_size_info (vlib_node_main_t * nm,
u32 n_scalar_bytes, u32 n_vector_bytes)
{
+#ifdef VLIB_SUPPORTS_ARBITRARY_SCALAR_SIZES
uword key = (n_scalar_bytes << 16) | n_vector_bytes;
uword *p, i;
}
return vec_elt_at_index (nm->frame_sizes, i);
+#else
+ ASSERT (vlib_frame_bytes (n_scalar_bytes, n_vector_bytes)
+ == (vlib_frame_bytes (0, 4)));
+ return vec_elt_at_index (nm->frame_sizes, 0);
+#endif
}
static u32
ASSERT (nf->frame_index != frame_index);
}
- f->frame_flags &= ~VLIB_FRAME_IS_ALLOCATED;
+ f->frame_flags &= ~(VLIB_FRAME_IS_ALLOCATED | VLIB_FRAME_NO_APPEND);
vec_add1 (fs->free_frame_indices, frame_index);
ASSERT (fs->n_alloc_frames > 0);
f->flags = 0;
}
- /* Allocate new frame if current one is already full. */
+ /* Allocate new frame if current one is marked as no-append or
+ it is already full. */
n_used = f->n_vectors;
- if (n_used >= VLIB_FRAME_SIZE || (allocate_new_next_frame && n_used > 0))
+ if (n_used >= VLIB_FRAME_SIZE || (allocate_new_next_frame && n_used > 0) ||
+ (f->frame_flags & VLIB_FRAME_NO_APPEND))
{
/* Old frame may need to be freed after dispatch, since we'll have
two redundant frames from node -> next node. */
return r;
}
-static inline void
-vlib_node_runtime_perf_counter (vlib_main_t * vm, u64 * pmc0, u64 * pmc1)
+always_inline void
+vlib_node_runtime_perf_counter (vlib_main_t * vm, u64 * pmc0, u64 * pmc1,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame, int before_or_after)
{
*pmc0 = 0;
*pmc1 = 0;
- if (PREDICT_FALSE (vm->vlib_node_runtime_perf_counter_cb != 0))
- (*vm->vlib_node_runtime_perf_counter_cb) (vm, pmc0, pmc1);
+ if (PREDICT_FALSE (vec_len (vm->vlib_node_runtime_perf_counter_cbs) != 0))
+ clib_call_callbacks (vm->vlib_node_runtime_perf_counter_cbs, vm, pmc0,
+ pmc1, node, frame, before_or_after);
}
always_inline void
(u32) (b->error), (u32) (b->ref_count),
(u32) (b->buffer_pool_index));
s = format (s,
- "trace_index: %d, len_not_first_buf: %d\n",
- b->trace_index, b->total_length_not_including_first_buffer);
+ "trace_handle: 0x%x, len_not_first_buf: %d\n",
+ b->trace_handle, b->total_length_not_including_first_buffer);
return s;
}
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
{
vlib_trace_header_t **h
- = pool_elt_at_index (tm->trace_buffer_pool, b->trace_index);
+ = pool_elt_at_index (tm->trace_buffer_pool,
+ vlib_buffer_get_trace_index (b));
vm->pcap_buffer = format (vm->pcap_buffer, "%U%c",
format_vlib_trace, vm, h[0], 0);
last_time_stamp, frame ? frame->n_vectors : 0,
/* is_after */ 0);
- vlib_node_runtime_perf_counter (vm, &pmc_before[0], &pmc_before[1]);
+ vlib_node_runtime_perf_counter (vm, &pmc_before[0], &pmc_before[1],
+ node, frame, 0 /* before */ );
/*
* Turn this on if you run into
* To validate accounting: pmc_delta = t - pmc_before;
* perf ticks should equal clocks/pkt...
*/
- vlib_node_runtime_perf_counter (vm, &pmc_after[0], &pmc_after[1]);
+ vlib_node_runtime_perf_counter (vm, &pmc_after[0], &pmc_after[1], node,
+ frame, 1 /* after */ );
pmc_delta[0] = pmc_after[0] - pmc_before[0];
pmc_delta[1] = pmc_after[1] - pmc_before[1];
VLIB_NODE_STATE_POLLING,
f, last_time_stamp);
- f->frame_flags &= ~VLIB_FRAME_PENDING;
+ f->frame_flags &= ~(VLIB_FRAME_PENDING | VLIB_FRAME_NO_APPEND);
/* Frame is ready to be used again, so restore it. */
if (restore_frame_index != ~0)
u64 cpu_time_now;
vlib_frame_queue_main_t *fqm;
u32 *last_node_runtime_indices = 0;
+ u32 frame_queue_check_counter = 0;
/* Initialize pending node vector. */
if (is_main)
if (is_main)
{
uword i;
+
+ /*
+ * Perform an initial barrier sync. Pays no attention to
+ * the barrier sync hold-down timer scheme, which won't work
+ * at this point in time.
+ */
+ vlib_worker_thread_initial_barrier_sync_and_release (vm);
+
nm->current_process_index = ~0;
for (i = 0; i < vec_len (nm->processes); i++)
cpu_time_now = dispatch_process (vm, nm->processes[i], /* frame */ 0,
if (!is_main)
{
vlib_worker_thread_barrier_check ();
- vec_foreach (fqm, tm->frame_queue_mains)
- vlib_frame_queue_dequeue (vm, fqm);
- if (PREDICT_FALSE (vm->worker_thread_main_loop_callback != 0))
- ((void (*)(vlib_main_t *)) vm->worker_thread_main_loop_callback)
- (vm);
+ if (PREDICT_FALSE (vm->check_frame_queues +
+ frame_queue_check_counter))
+ {
+ u32 processed = 0;
+
+ if (vm->check_frame_queues)
+ {
+ frame_queue_check_counter = 100;
+ vm->check_frame_queues = 0;
+ }
+
+ vec_foreach (fqm, tm->frame_queue_mains)
+ processed += vlib_frame_queue_dequeue (vm, fqm);
+
+ /* No handoff queue work found? */
+ if (processed)
+ frame_queue_check_counter = 100;
+ else
+ frame_queue_check_counter--;
+ }
+ if (PREDICT_FALSE (vec_len (vm->worker_thread_main_loop_callbacks)))
+ clib_call_callbacks (vm->worker_thread_main_loop_callbacks, vm);
}
/* Process pre-input nodes. */
foreach_weak_reference_stub;
#undef _
+void vl_api_set_elog_main (elog_main_t * m) __attribute__ ((weak));
+void
+vl_api_set_elog_main (elog_main_t * m)
+{
+ clib_warning ("STUB");
+}
+
+int vl_api_set_elog_trace_api_messages (int enable) __attribute__ ((weak));
+int
+vl_api_set_elog_trace_api_messages (int enable)
+{
+ clib_warning ("STUB");
+ return 0;
+}
+
+int vl_api_get_elog_trace_api_messages (void) __attribute__ ((weak));
+int
+vl_api_get_elog_trace_api_messages (void)
+{
+ clib_warning ("STUB");
+ return 0;
+}
+
/* Main function. */
int
vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
vm->elog_main.event_ring_size = 128 << 10;
elog_init (&vm->elog_main, vm->elog_main.event_ring_size);
elog_enable_disable (&vm->elog_main, 1);
+ vl_api_set_elog_main (&vm->elog_main);
+ (void) vl_api_set_elog_trace_api_messages (1);
/* Default name. */
if (!vm->name)
goto done;
}
- if ((error = vlib_buffer_main_init (vm)))
+ if ((error = vlib_map_stat_segment_init (vm)))
{
clib_error_report (error);
goto done;
}
- if ((error = vlib_thread_init (vm)))
+ if ((error = vlib_buffer_main_init (vm)))
{
clib_error_report (error);
goto done;
}
- if ((error = vlib_map_stat_segment_init (vm)))
+ if ((error = vlib_thread_init (vm)))
{
clib_error_report (error);
goto done;
vec_validate (vm->processing_rpc_requests, 0);
_vec_len (vm->processing_rpc_requests) = 0;
+ if ((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))
+ goto done;
+
+ /* Sort per-thread init functions before we start threads */
+ vlib_sort_init_exit_functions (&vm->worker_init_function_registrations);
+
+ /* Call all main loop enter functions. */
+ {
+ clib_error_t *sub_error;
+ sub_error = vlib_call_all_main_loop_enter_functions (vm);
+ if (sub_error)
+ clib_error_report (sub_error);
+ }
+
switch (clib_setjmp (&vm->main_loop_exit, VLIB_MAIN_LOOP_EXIT_NONE))
{
case VLIB_MAIN_LOOP_EXIT_NONE:
goto done;
}
- if ((error = vlib_call_all_config_functions (vm, input, 0 /* is_early */ )))
- goto done;
-
- /* Call all main loop enter functions. */
- {
- clib_error_t *sub_error;
- sub_error = vlib_call_all_main_loop_enter_functions (vm);
- if (sub_error)
- clib_error_report (sub_error);
- }
-
vlib_main_loop (vm);
done:
unformat_input_t * input,
vlib_cli_command_t * cmd, int rx_tx)
{
-#define PCAP_DEF_PKT_TO_CAPTURE (100)
-
unformat_input_t _line_input, *line_input = &_line_input;
pcap_main_t *pm = &vm->dispatch_pcap_main;
- u8 *filename;
- u8 *chroot_filename = 0;
- u32 max = 0;
+ u8 *filename = 0;
+ u32 max = 1000;
int enabled = 0;
- int errorFlag = 0;
+ int is_error = 0;
clib_error_t *error = 0;
u32 node_index, add;
vlib_trace_main_t *tm;
else
{
vlib_cli_output (vm, "pcap dispatch capture already on...");
- errorFlag = 1;
+ is_error = 1;
break;
}
}
else
{
vlib_cli_output (vm, "pcap tx capture already off...");
- errorFlag = 1;
+ is_error = 1;
break;
}
}
vlib_cli_output
(vm,
"can't change max value while pcap tx capture active...");
- errorFlag = 1;
+ is_error = 1;
break;
}
pm->n_packets_to_capture = max;
{
vlib_cli_output
(vm, "can't change file while pcap tx capture active...");
- errorFlag = 1;
+ is_error = 1;
break;
}
}
{
error = clib_error_return (0, "unknown input `%U'",
format_unformat_error, line_input);
- errorFlag = 1;
+ is_error = 1;
break;
}
}
unformat_free (line_input);
-
- if (errorFlag == 0)
+ if (is_error == 0)
{
- /* Since no error, save configured values. */
- if (chroot_filename)
- {
- if (pm->file_name)
- vec_free (pm->file_name);
- vec_add1 (chroot_filename, 0);
- pm->file_name = (char *) chroot_filename;
- }
+ /* Clean up from previous run */
+ vec_free (pm->file_name);
+ vec_free (pm->pcap_data);
- if (max)
- pm->n_packets_to_capture = max;
+ memset (pm, 0, sizeof (*pm));
+ pm->n_packets_to_capture = max;
if (enabled)
{
- if (pm->file_name == 0)
- pm->file_name = (char *) format (0, "/tmp/dispatch.pcap%c", 0);
+ 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)
vlib_cli_output (vm, "pcap dispatch capture on...");
}
}
- else if (chroot_filename)
- vec_free (chroot_filename);
return error;
}