f->vector_offset = to_node->vector_offset;
f->aux_offset = to_node->aux_offset;
f->flags = 0;
+ f->frame_size_index = to_node->frame_size_index;
fs->n_alloc_frames += 1;
/* Free given frame. */
void
-vlib_frame_free (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_frame_t * f)
+vlib_frame_free (vlib_main_t *vm, vlib_frame_t *f)
{
vlib_node_main_t *nm = &vm->node_main;
- vlib_node_t *node;
vlib_frame_size_t *fs;
ASSERT (vm == vlib_get_main ());
ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
- node = vlib_get_node (vm, r->node_index);
- fs = vec_elt_at_index (nm->frame_sizes, node->frame_size_index);
+ fs = vec_elt_at_index (nm->frame_sizes, f->frame_size_index);
ASSERT (f->frame_flags & VLIB_FRAME_IS_ALLOCATED);
}
f->frame_flags &= ~(VLIB_FRAME_IS_ALLOCATED | VLIB_FRAME_NO_APPEND);
+ f->flags = 0;
vec_add1 (fs->free_frames, f);
ASSERT (fs->n_alloc_frames > 0);
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_frame_stats_cli, static) = {
.path = "show vlib frame-allocation",
.short_help = "Show node dispatch frame statistics",
.function = show_frame_stats,
};
-/* *INDENT-ON* */
/* Change ownership of enqueue rights to given next node. */
static void
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_clear_cli, static) = {
.path = "event-logger clear",
.short_help = "Clear the event log",
.function = vlib_cli_elog_clear,
};
-/* *INDENT-ON* */
#ifdef CLIB_UNIX
static clib_error_t *
(vgm->post_mortem_callbacks[i]) ();
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_save_cli, static) = {
.path = "event-logger save",
.short_help = "event-logger save <filename> (saves log in /tmp/<filename>)",
.function = elog_save_buffer,
};
-/* *INDENT-ON* */
static clib_error_t *
elog_stop (vlib_main_t * vm,
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_stop_cli, static) = {
.path = "event-logger stop",
.short_help = "Stop the event-logger",
.function = elog_stop,
};
-/* *INDENT-ON* */
static clib_error_t *
elog_restart (vlib_main_t * vm,
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_restart_cli, static) = {
.path = "event-logger restart",
.short_help = "Restart the event-logger",
.function = elog_restart,
};
-/* *INDENT-ON* */
static clib_error_t *
elog_resize_command_fn (vlib_main_t * vm,
return 0;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_resize_cli, static) = {
.path = "event-logger resize",
.short_help = "event-logger resize <nnn>",
.function = elog_resize_command_fn,
};
-/* *INDENT-ON* */
#endif /* CLIB_UNIX */
return error;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (elog_show_cli, static) = {
.path = "show event-logger",
.short_help = "Show event logger info",
.function = elog_show_buffer,
};
-/* *INDENT-ON* */
void
vlib_gdb_show_event_log (void)
polling mode and vice versa. */
if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_ADAPTIVE_MODE))
{
- /* *INDENT-OFF* */
ELOG_TYPE_DECLARE (e) =
{
.function = (char *) __FUNCTION__,
"interrupt", "polling",
},
};
- /* *INDENT-ON* */
struct
{
u32 node_name, vector_length, is_polling;
/* no new frame has been assigned to this node, use the saved one */
nf->frame = restore_frame;
f->n_vectors = 0;
+ f->flags = 0;
}
else
{
/* The node has gained a frame, implying packets from the current frame
were re-queued to this same node. we don't need the saved one
anymore */
- vlib_frame_free (vm, n, f);
+ vlib_frame_free (vm, f);
}
}
else
if (f->frame_flags & VLIB_FRAME_FREE_AFTER_DISPATCH)
{
ASSERT (!(n->flags & VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH));
- vlib_frame_free (vm, n, f);
+ vlib_frame_free (vm, f);
}
}
{
vlib_node_main_t *nm = &vm->node_main;
vlib_process_t *p = vec_elt (nm->processes, process_index);
- dispatch_process (vm, p, /* frame */ 0, /* cpu_time_now */ 0);
+ u64 cpu_time_now = clib_cpu_time_now ();
+ dispatch_process (vm, p, /* frame */ 0, cpu_time_now);
}
static u64
return t;
}
-void vl_api_send_pending_rpc_requests (vlib_main_t *) __attribute__ ((weak));
-void
-vl_api_send_pending_rpc_requests (vlib_main_t * vm)
-{
-}
-
static_always_inline void
vlib_main_or_worker_loop (vlib_main_t * vm, int is_main)
{
else
cpu_time_now = clib_cpu_time_now ();
- /* Pre-allocate interupt runtime indices and lock. */
- vec_alloc_aligned (nm->pending_interrupts, 1, CLIB_CACHE_LINE_BYTES);
-
/* Pre-allocate expired nodes. */
if (!nm->polling_threshold_vector_length)
nm->polling_threshold_vector_length = 10;
if (PREDICT_FALSE (_vec_len (vm->pending_rpc_requests) > 0))
{
if (!is_main)
- vl_api_send_pending_rpc_requests (vm);
+ vlib_worker_flush_pending_rpc_requests (vm);
}
if (!is_main)
if (PREDICT_FALSE (vm->check_frame_queues + frame_queue_check_counter))
{
u32 processed = 0;
- vlib_frame_queue_dequeue_fn_t *fn =
- vlib_buffer_func_main.frame_queue_dequeue_fn;
+ vlib_frame_queue_dequeue_fn_t *fn;
if (vm->check_frame_queues)
{
}
vec_foreach (fqm, tm->frame_queue_mains)
- processed += (fn) (vm, fqm);
+ {
+ fn = fqm->frame_queue_dequeue_fn;
+ processed += (fn) (vm, fqm);
+ }
/* No handoff queue work found? */
if (processed)
/* frame */ 0,
cpu_time_now);
+ if (clib_interrupt_is_any_pending (nm->pre_input_node_interrupts))
+ {
+ int int_num = -1;
+
+ while ((int_num = clib_interrupt_get_next_and_clear (
+ nm->pre_input_node_interrupts, int_num)) != -1)
+ {
+ vlib_node_runtime_t *n;
+ n = vec_elt_at_index (
+ nm->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT], int_num);
+ cpu_time_now = dispatch_node (vm, n, VLIB_NODE_TYPE_PRE_INPUT,
+ VLIB_NODE_STATE_INTERRUPT,
+ /* frame */ 0, cpu_time_now);
+ }
+ }
+
/* Next process input nodes. */
vec_foreach (n, nm->nodes_by_type[VLIB_NODE_TYPE_INPUT])
cpu_time_now = dispatch_node (vm, n,
if (PREDICT_TRUE (is_main && vm->queue_signal_pending == 0))
vm->queue_signal_callback (vm);
- if (__atomic_load_n (nm->pending_interrupts, __ATOMIC_ACQUIRE))
+ if (clib_interrupt_is_any_pending (nm->input_node_interrupts))
{
int int_num = -1;
- *nm->pending_interrupts = 0;
- while ((int_num =
- clib_interrupt_get_next (nm->interrupts, int_num)) != -1)
+ while ((int_num = clib_interrupt_get_next_and_clear (
+ nm->input_node_interrupts, int_num)) != -1)
{
vlib_node_runtime_t *n;
- clib_interrupt_clear (nm->interrupts, int_num);
n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT],
int_num);
cpu_time_now = dispatch_node (vm, n, VLIB_NODE_TYPE_INPUT,
if (is_main)
{
- /* *INDENT-OFF* */
ELOG_TYPE_DECLARE (es) =
{
.format = "process tw start",
.format = "process tw end: %d",
.format_args = "i4",
};
- /* *INDENT-ON* */
struct
{
if (PREDICT_FALSE (vm->elog_trace_graph_dispatch))
ed = ELOG_DATA (&vlib_global_main.elog_main, es);
- nm->data_from_advancing_timing_wheel =
- TW (tw_timer_expire_timers_vec)
- ((TWT (tw_timer_wheel) *) nm->timing_wheel, vlib_time_now (vm),
- nm->data_from_advancing_timing_wheel);
+ TW (tw_timer_expire_timers)
+ ((TWT (tw_timer_wheel) *) nm->timing_wheel, vlib_time_now (vm));
ASSERT (nm->data_from_advancing_timing_wheel != 0);
vlib_get_node (vm, te->process_node_index);
vlib_process_t *p =
vec_elt (nm->processes, n->runtime_index);
+ p->stop_timer_handle = ~0;
void *data;
data =
vlib_process_signal_event_helper (nm, n, p,
return 0;
}
+static void
+process_expired_timer_cb (u32 *expired_timer_handles)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ vlib_node_main_t *nm = &vm->node_main;
+ u32 *handle;
+
+ vec_foreach (handle, expired_timer_handles)
+ {
+ u32 pi = vlib_timing_wheel_data_get_index (*handle);
+ vlib_process_t *p = vec_elt (nm->processes, pi);
+
+ p->stop_timer_handle = ~0;
+ }
+ vec_append (nm->data_from_advancing_timing_wheel, expired_timer_handles);
+}
+
/* Main function. */
int
vlib_main (vlib_main_t * volatile vm, unformat_input_t * input)
vec_set_len (nm->data_from_advancing_timing_wheel, 0);
/* Create the process timing wheel */
- TW (tw_timer_wheel_init) ((TWT (tw_timer_wheel) *) nm->timing_wheel,
- 0 /* no callback */ ,
- 10e-6 /* timer period 10us */ ,
- ~0 /* max expirations per call */ );
+ TW (tw_timer_wheel_init)
+ ((TWT (tw_timer_wheel) *) nm->timing_wheel,
+ process_expired_timer_cb /* callback */, 10e-6 /* timer period 10us */,
+ ~0 /* max expirations per call */);
vec_validate (vm->pending_rpc_requests, 0);
vec_set_len (vm->pending_rpc_requests, 0);
vlib_main_loop (vm);
done:
+ /* Stop worker threads, barrier will not be released */
vlib_worker_thread_barrier_sync (vm);
+
/* Call all exit functions. */
{
clib_error_t *sub_error;
if (sub_error)
clib_error_report (sub_error);
}
- vlib_worker_thread_barrier_release (vm);
if (error)
clib_error_report (error);