for (i = 0; i < vec_len (tm->registrations); i++)
{
vlib_node_main_t *nm, *nm_clone;
- vlib_buffer_free_list_t *fl_clone, *fl_orig;
- vlib_buffer_free_list_t *orig_freelist_pool;
int k;
tr = tm->registrations[i];
/* fork the frame dispatch queue */
nm_clone->pending_frames = 0;
- vec_validate (nm_clone->pending_frames, 10); /* $$$$$?????? */
+ vec_validate (nm_clone->pending_frames, 10);
_vec_len (nm_clone->pending_frames) = 0;
/* fork nodes */
n->runtime_data_bytes));
}
+ nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT] =
+ vec_dup_aligned (nm->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT],
+ CLIB_CACHE_LINE_BYTES);
+ vec_foreach (rt,
+ nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT])
+ {
+ vlib_node_t *n = vlib_get_node (vm, rt->node_index);
+ rt->thread_index = vm_clone->thread_index;
+ /* copy initial runtime_data from node */
+ if (n->runtime_data && n->runtime_data_bytes > 0)
+ clib_memcpy (rt->runtime_data, n->runtime_data,
+ clib_min (VLIB_NODE_RUNTIME_DATA_SIZE,
+ n->runtime_data_bytes));
+ }
+
nm_clone->processes = vec_dup_aligned (nm->processes,
CLIB_CACHE_LINE_BYTES);
(vlib_mains[0]->error_main.counters_last_clear,
CLIB_CACHE_LINE_BYTES);
- /* Fork the vlib_buffer_main_t free lists, etc. */
- orig_freelist_pool = vm_clone->buffer_free_list_pool;
- vm_clone->buffer_free_list_pool = 0;
-
- /* *INDENT-OFF* */
- pool_foreach (fl_orig, orig_freelist_pool,
- ({
- pool_get_aligned (vm_clone->buffer_free_list_pool,
- fl_clone, CLIB_CACHE_LINE_BYTES);
- ASSERT (fl_orig - orig_freelist_pool
- == fl_clone - vm_clone->buffer_free_list_pool);
-
- fl_clone[0] = fl_orig[0];
- fl_clone->buffers = 0;
- vec_validate(fl_clone->buffers, 0);
- vec_reset_length(fl_clone->buffers);
- fl_clone->n_alloc = 0;
- }));
-/* *INDENT-ON* */
-
worker_thread_index++;
}
}
vec_free (old_rt);
+ /* re-clone pre-input nodes */
+ old_rt = nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT];
+ nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT] =
+ vec_dup_aligned (nm->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT],
+ CLIB_CACHE_LINE_BYTES);
+
+ vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_PRE_INPUT])
+ {
+ vlib_node_t *n = vlib_get_node (vm, rt->node_index);
+ rt->thread_index = vm_clone->thread_index;
+ /* copy runtime_data, will be overwritten later for existing rt */
+ if (n->runtime_data && n->runtime_data_bytes > 0)
+ clib_memcpy_fast (rt->runtime_data, n->runtime_data,
+ clib_min (VLIB_NODE_RUNTIME_DATA_SIZE,
+ n->runtime_data_bytes));
+ }
+
+ for (j = 0; j < vec_len (old_rt); j++)
+ {
+ rt = vlib_node_get_runtime (vm_clone, old_rt[j].node_index);
+ rt->state = old_rt[j].state;
+ clib_memcpy_fast (rt->runtime_data, old_rt[j].runtime_data,
+ VLIB_NODE_RUNTIME_DATA_SIZE);
+ }
+
+ vec_free (old_rt);
+
nm_clone->processes = vec_dup_aligned (nm->processes,
CLIB_CACHE_LINE_BYTES);
}
#endif
void
-vlib_worker_thread_barrier_sync_int (vlib_main_t * vm)
+vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name)
{
f64 deadline;
f64 now;
ASSERT (vlib_get_thread_index () == 0);
+ vlib_worker_threads[0].barrier_caller = func_name;
count = vec_len (vlib_mains) - 1;
/* Record entry relative to last close */
deadline = now + BARRIER_SYNC_TIMEOUT;
+ /*
+ * Note when we let go of the barrier.
+ * Workers can use this to derive a reasonably accurate
+ * time offset. See vlib_time_now(...)
+ */
+ vm->time_last_barrier_release = vlib_time_now (vm);
+ CLIB_MEMORY_STORE_BARRIER ();
+
*vlib_worker_threads->wait_at_barrier = 0;
while (*vlib_worker_threads->workers_at_barrier > 0)
ASSERT (vm->thread_index == vlib_get_thread_index ());
- vm->cpu_index = clib_get_current_cpu_index ();
- vm->numa_node = clib_get_current_numa_node ();
-
vlib_worker_thread_init (w);
clib_time_init (&vm->clib_time);
clib_mem_set_heap (w->thread_mheap);
VLIB_INIT_FUNCTION (threads_init);
+
+static clib_error_t *
+show_clock_command_fn (vlib_main_t * vm,
+ unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+ int i;
+ f64 now;
+
+ now = vlib_time_now (vm);
+
+ vlib_cli_output (vm, "Time now %.9f", now);
+
+ if (vec_len (vlib_mains) == 1)
+ return 0;
+
+ vlib_cli_output (vm, "Time last barrier release %.9f",
+ vm->time_last_barrier_release);
+
+ for (i = 1; i < vec_len (vlib_mains); i++)
+ {
+ if (vlib_mains[i] == 0)
+ continue;
+ vlib_cli_output (vm, "Thread %d offset %.9f error %.9f", i,
+ vlib_mains[i]->time_offset,
+ vm->time_last_barrier_release -
+ vlib_mains[i]->time_last_barrier_release);
+ }
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (f_command, static) =
+{
+ .path = "show clock",
+ .short_help = "show clock",
+ .function = show_clock_command_fn,
+};
+/* *INDENT-ON* */
+
/*
* fd.io coding-style-patch-verification: ON
*