X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fnode.c;h=0066037360701690527a3809dce878f74156f47d;hb=fc639ff2d7abd8599f59078fac99f731026215b3;hp=805c69e4f8bf0fe63cd18a7ecd4190ea9fc7cd13;hpb=1ddbc0138b64486b8e51e5e12fcad21fba8b8b68;p=vpp.git diff --git a/src/vlib/node.c b/src/vlib/node.c index 805c69e4f8b..00660373607 100644 --- a/src/vlib/node.c +++ b/src/vlib/node.c @@ -47,8 +47,7 @@ vlib_get_node_by_name (vlib_main_t * vm, u8 * name) vlib_node_main_t *nm = &vm->node_main; uword *p; u8 *key = name; - if (!clib_mem_is_heap_object (key)) - key = format (0, "%s", key); + key = format (0, "%s", key); p = hash_get (nm->node_by_name, key); if (key != name) vec_free (key); @@ -72,32 +71,6 @@ 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, ...) { @@ -115,7 +88,7 @@ vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) node_set_elog_name (vm, node_index); /* Propagate the change to all worker threads */ - vlib_worker_thread_node_rename (node_index); + vlib_worker_thread_node_runtime_update (); } static void @@ -128,10 +101,6 @@ vlib_node_runtime_update (vlib_main_t * vm, u32 node_index, u32 next_index) vlib_pending_frame_t *pf; i32 i, j, n_insert; - ASSERT (vlib_get_thread_index () == 0); - - vlib_worker_thread_barrier_sync (vm); - node = vec_elt (nm->nodes, node_index); r = vlib_node_get_runtime (vm, node_index); @@ -176,8 +145,6 @@ vlib_node_runtime_update (vlib_main_t * vm, u32 node_index, u32 next_index) nf->node_runtime_index = next_node->runtime_index; vlib_worker_thread_node_runtime_update (); - - vlib_worker_thread_barrier_release (vm); } uword @@ -207,9 +174,12 @@ vlib_node_add_next_with_slot (vlib_main_t * vm, uword next_node_index, uword slot) { vlib_node_main_t *nm = &vm->node_main; - vlib_node_t *node, *next; + vlib_node_t *node, *next, *old_next; + u32 old_next_index; uword *p; + ASSERT (vlib_get_thread_index () == 0); + node = vec_elt (nm->nodes, node_index); next = vec_elt (nm->nodes, next_node_index); @@ -224,12 +194,22 @@ vlib_node_add_next_with_slot (vlib_main_t * vm, return p[0]; } + vlib_worker_thread_barrier_sync (vm); + if (slot == ~0) slot = vec_len (node->next_nodes); vec_validate_init_empty (node->next_nodes, slot, ~0); vec_validate (node->n_vectors_by_next_node, slot); + if ((old_next_index = node->next_nodes[slot]) != ~0u) + { + hash_unset (node->next_slot_by_node, old_next_index); + old_next = vlib_get_node (vm, old_next_index); + old_next->prev_node_bitmap = + clib_bitmap_andnoti (old_next->prev_node_bitmap, node_index); + } + node->next_nodes[slot] = next_node_index; hash_set (node->next_slot_by_node, next_node_index, slot); @@ -254,6 +234,7 @@ vlib_node_add_next_with_slot (vlib_main_t * vm, /* *INDENT-ON* */ } + vlib_worker_thread_barrier_release (vm); return slot; } @@ -290,7 +271,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. */ @@ -314,7 +295,6 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) { vlib_node_main_t *nm = &vm->node_main; vlib_node_t *n; - u32 page_size = clib_mem_get_page_size (); int i; if (CLIB_DEBUG > 0) @@ -347,8 +327,10 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) 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); @@ -364,7 +346,10 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) /* Node names must be unique. */ { - vlib_node_t *o = vlib_get_node_by_name (vm, n->name); + /* vlib_get_node_by_name() expects NULL-terminated strings */ + u8 *name = format (0, "%v%c", n->name, 0); + vlib_node_t *o = vlib_get_node_by_name (vm, name); + vec_free (name); if (o) clib_error ("more than one node named `%v'", n->name); } @@ -425,33 +410,24 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) vlib_process_t *p; uword log2_n_stack_bytes; - log2_n_stack_bytes = clib_max (r->process_log2_n_stack_bytes, 15); + log2_n_stack_bytes = clib_max (r->process_log2_n_stack_bytes, + VLIB_PROCESS_LOG2_STACK_SIZE); + log2_n_stack_bytes = clib_max (log2_n_stack_bytes, + clib_mem_get_log2_page_size ()); -#ifdef CLIB_UNIX - /* - * Bump the stack size if running over a kernel with a large page size, - * and the stack isn't any too big to begin with. Otherwise, we'll - * trip over the stack guard page for sure. - */ - if ((page_size > (4 << 10)) && log2_n_stack_bytes < 19) - { - if ((1 << log2_n_stack_bytes) <= page_size) - log2_n_stack_bytes = min_log2 (page_size) + 1; - else - log2_n_stack_bytes++; - } -#endif + p = clib_mem_alloc_aligned (sizeof (p[0]), CLIB_CACHE_LINE_BYTES); + clib_memset (p, 0, sizeof (p[0])); + p->log2_n_stack_bytes = log2_n_stack_bytes; - p = clib_mem_alloc_aligned_at_offset - (sizeof (p[0]) + (1 << log2_n_stack_bytes), - STACK_ALIGN, STRUCT_OFFSET_OF (vlib_process_t, stack), - 0 /* no, don't call os_out_of_memory */ ); - if (p == 0) - clib_panic ("failed to allocate process stack (%d bytes)", - 1 << log2_n_stack_bytes); + p->stack = clib_mem_vm_map_stack (1ULL << log2_n_stack_bytes, + CLIB_MEM_PAGE_SZ_DEFAULT, + "process stack: %U", + format_vlib_node_name, vm, + n->index); - memset (p, 0, sizeof (p[0])); - p->log2_n_stack_bytes = log2_n_stack_bytes; + if (p->stack == CLIB_MEM_VM_MAP_FAILED) + clib_panic ("failed to allocate process stack (%d bytes)", + 1ULL << log2_n_stack_bytes); /* Process node's runtime index is really index into process pointer vector. */ @@ -465,16 +441,6 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) /* Node runtime is stored inside of process. */ rt = &p->node_runtime; - -#ifdef CLIB_UNIX - /* - * Disallow writes to the bottom page of the stack, to - * catch stack overflows. - */ - if (mprotect (p->stack, page_size, PROT_READ) < 0) - clib_unix_warning ("process stack"); -#endif - } else { @@ -500,7 +466,7 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r) vec_resize (rt->errors, r->n_errors); for (i = 0; i < vec_len (rt->errors); i++) - rt->errors[i] = vlib_error_set (n->index, i); + rt->errors[i] = n->error_heap_index + i; STATIC_ASSERT_SIZEOF (vlib_node_runtime_t, 128); ASSERT (vec_len (n->runtime_data) <= VLIB_NODE_RUNTIME_DATA_SIZE); @@ -528,7 +494,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; @@ -633,7 +599,10 @@ vlib_node_main_init (vlib_main_t * vm) vlib_node_t *n; uword ni; + nm->frame_sizes = vec_new (vlib_frame_size_t, 1); +#ifdef VLIB_SUPPORTS_ARBITRARY_SCALAR_SIZES nm->frame_size_hash = hash_create (0, sizeof (uword)); +#endif nm->flags |= VLIB_NODE_MAIN_RUNTIME_STARTED; /* Generate sibling relationships */ @@ -752,6 +721,34 @@ done: return error; } +u32 +vlib_process_create (vlib_main_t * vm, char *name, + vlib_node_function_t * f, u32 log2_n_stack_bytes) +{ + vlib_node_registration_t r; + vlib_node_t *n; + + memset (&r, 0, sizeof (r)); + + r.name = (char *) format (0, "%s", name, 0); + r.function = f; + r.process_log2_n_stack_bytes = log2_n_stack_bytes; + r.type = VLIB_NODE_TYPE_PROCESS; + + vlib_worker_thread_barrier_sync (vm); + + vlib_register_node (vm, &r); + vec_free (r.name); + + vlib_worker_thread_node_runtime_update (); + vlib_worker_thread_barrier_release (vm); + + n = vlib_get_node (vm, r.index); + vlib_start_process (vm, n->runtime_index); + + return (r.index); +} + /* * fd.io coding-style-patch-verification: ON *