X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvlib%2Fnode.c;h=69f505143b2ddcfc38d986e3c4763cad92173459;hb=fe4827c97d375d5849aa5db863030af48069bdc2;hp=2cda0f064759a8b9d1f8f08aff9f4e0e3015d3d5;hpb=bb620d74b247f419eb485886c55148099b0213bb;p=vpp.git diff --git a/src/vlib/node.c b/src/vlib/node.c index 2cda0f06475..69f505143b2 100644 --- a/src/vlib/node.c +++ b/src/vlib/node.c @@ -72,6 +72,32 @@ node_set_elog_name (vlib_main_t * vm, uword node_index) n->name_elog_string = elog_string (&vm->elog_main, "%v%c", n->name, 0); } +static void +vlib_worker_thread_node_rename (u32 node_index) +{ + int i; + vlib_main_t *vm; + vlib_node_t *n; + + if (vec_len (vlib_mains) == 1) + return; + + vm = vlib_mains[0]; + n = vlib_get_node (vm, node_index); + + ASSERT (vlib_get_thread_index () == 0); + ASSERT (*vlib_worker_threads->wait_at_barrier == 1); + + for (i = 1; i < vec_len (vlib_mains); i++) + { + vlib_main_t *vm_worker = vlib_mains[i]; + vlib_node_t *n_worker = vlib_get_node (vm_worker, node_index); + + n_worker->name = n->name; + n_worker->name_elog_string = n->name_elog_string; + } +} + void vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) { @@ -87,6 +113,9 @@ vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) hash_set (nm->node_by_name, n->name, n->index); node_set_elog_name (vm, node_index); + + /* Propagate the change to all worker threads */ + vlib_worker_thread_node_rename (node_index); } static void @@ -261,7 +290,7 @@ node_elog_init (vlib_main_t * vm, uword ni) { elog_event_type_t t; - memset (&t, 0, sizeof (t)); + clib_memset (&t, 0, sizeof (t)); /* 2 event types for this node: one when node function is called. One when it returns. */ @@ -295,11 +324,33 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) ASSERT (VLIB_NODE_TYPE_INTERNAL == zero.type); } + if (r->node_fn_registrations) + { + vlib_node_fn_registration_t *fnr = r->node_fn_registrations; + int priority = -1; + + /* to avoid confusion, please remove ".function " statiement from + CLIB_NODE_REGISTRATION() if using function function candidates */ + ASSERT (r->function == 0); + + while (fnr) + { + if (fnr->priority > priority) + { + priority = fnr->priority; + r->function = fnr->function; + } + fnr = fnr->next_registration; + } + } + ASSERT (r->function != 0); n = clib_mem_alloc_no_fail (sizeof (n[0])); - memset (n, 0, sizeof (n[0])); + clib_memset (n, 0, sizeof (n[0])); n->index = vec_len (nm->nodes); + n->node_fn_registrations = r->node_fn_registrations; + n->protocol_hint = r->protocol_hint; vec_add1 (nm->nodes, n); @@ -401,7 +452,7 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) clib_panic ("failed to allocate process stack (%d bytes)", 1 << log2_n_stack_bytes); - memset (p, 0, sizeof (p[0])); + clib_memset (p, 0, sizeof (p[0])); p->log2_n_stack_bytes = log2_n_stack_bytes; /* Process node's runtime index is really index into process @@ -479,7 +530,7 @@ null_node_fn (vlib_main_t * vm, u16 n_vectors = frame->n_vectors; vlib_node_increment_counter (vm, node->node_index, 0, n_vectors); - vlib_buffer_free (vm, vlib_frame_args (frame), n_vectors); + vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_vectors); vlib_frame_free (vm, node, frame); return n_vectors; @@ -514,6 +565,68 @@ vlib_register_all_static_nodes (vlib_main_t * vm) } } +void +vlib_node_get_nodes (vlib_main_t * vm, u32 max_threads, int include_stats, + int barrier_sync, vlib_node_t **** node_dupsp, + vlib_main_t *** stat_vmsp) +{ + vlib_node_main_t *nm = &vm->node_main; + vlib_node_t *n; + vlib_node_t ***node_dups = *node_dupsp; + vlib_node_t **nodes; + vlib_main_t **stat_vms = *stat_vmsp; + vlib_main_t *stat_vm; + uword i, j; + u32 threads_to_serialize; + + if (vec_len (stat_vms) == 0) + { + for (i = 0; i < vec_len (vlib_mains); i++) + { + stat_vm = vlib_mains[i]; + if (stat_vm) + vec_add1 (stat_vms, stat_vm); + } + } + + threads_to_serialize = clib_min (max_threads, vec_len (stat_vms)); + + vec_validate (node_dups, threads_to_serialize - 1); + + /* + * Barrier sync across stats scraping. + * Otherwise, the counts will be grossly inaccurate. + */ + if (barrier_sync) + vlib_worker_thread_barrier_sync (vm); + + for (j = 0; j < threads_to_serialize; j++) + { + stat_vm = stat_vms[j]; + nm = &stat_vm->node_main; + + if (include_stats) + { + for (i = 0; i < vec_len (nm->nodes); i++) + { + n = nm->nodes[i]; + vlib_node_sync_stats (stat_vm, n); + } + } + + nodes = node_dups[j]; + vec_validate (nodes, vec_len (nm->nodes) - 1); + clib_memcpy (nodes, nm->nodes, vec_len (nm->nodes) * sizeof (nodes[0])); + node_dups[j] = nodes; + } + + if (barrier_sync) + vlib_worker_thread_barrier_release (vm); + + *node_dupsp = node_dups; + *stat_vmsp = stat_vms; +} + clib_error_t * vlib_node_main_init (vlib_main_t * vm) {