X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fthreads.c;h=499a626e4701be08ffcbff16f45824697262f290;hb=a606d92107d4bf0107c3f54e2c87d39311f82075;hp=0fc306db6f25ab210a9004840ab6d4e6df5acd13;hpb=4537c30925050ffa34c33e6a481f07f1ec0a01ff;p=vpp.git diff --git a/src/vlib/threads.c b/src/vlib/threads.c index 0fc306db6f2..499a626e470 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -47,13 +48,11 @@ barrier_trace_sync (f64 t_entry, f64 t_open, f64 t_closed) if (!vlib_worker_threads->barrier_elog_enabled) return; - /* *INDENT-OFF* */ - ELOG_TYPE_DECLARE (e) = - { - .format = "bar-trace-%s-#%d", - .format_args = "T4i4", - }; - /* *INDENT-ON* */ + ELOG_TYPE_DECLARE (e) = { + .format = "bar-trace-%s-#%d", + .format_args = "T4i4", + }; + struct { u32 caller, count, t_entry, t_open, t_closed; @@ -74,13 +73,11 @@ barrier_trace_sync_rec (f64 t_entry) if (!vlib_worker_threads->barrier_elog_enabled) return; - /* *INDENT-OFF* */ - ELOG_TYPE_DECLARE (e) = - { - .format = "bar-syncrec-%s-#%d", - .format_args = "T4i4", - }; - /* *INDENT-ON* */ + ELOG_TYPE_DECLARE (e) = { + .format = "bar-syncrec-%s-#%d", + .format_args = "T4i4", + }; + struct { u32 caller, depth; @@ -98,13 +95,11 @@ barrier_trace_release_rec (f64 t_entry) if (!vlib_worker_threads->barrier_elog_enabled) return; - /* *INDENT-OFF* */ - ELOG_TYPE_DECLARE (e) = - { - .format = "bar-relrrec-#%d", - .format_args = "i4", - }; - /* *INDENT-ON* */ + ELOG_TYPE_DECLARE (e) = { + .format = "bar-relrrec-#%d", + .format_args = "i4", + }; + struct { u32 depth; @@ -120,13 +115,11 @@ barrier_trace_release (f64 t_entry, f64 t_closed_total, f64 t_update_main) if (!vlib_worker_threads->barrier_elog_enabled) return; - /* *INDENT-OFF* */ - ELOG_TYPE_DECLARE (e) = - { - .format = "bar-rel-#%d-e%d-u%d-t%d", - .format_args = "i4i4i4i4", - }; - /* *INDENT-ON* */ + ELOG_TYPE_DECLARE (e) = { + .format = "bar-rel-#%d-e%d-u%d-t%d", + .format_args = "i4i4i4i4", + }; + struct { u32 count, t_entry, t_update_main, t_closed_total; @@ -173,33 +166,6 @@ sort_registrations_by_no_clone (void *a0, void *a1) - ((i32) ((*tr1)->no_data_structure_clone))); } -static uword * -clib_sysfs_list_to_bitmap (char *filename) -{ - FILE *fp; - uword *r = 0; - - fp = fopen (filename, "r"); - - if (fp != NULL) - { - u8 *buffer = 0; - vec_validate (buffer, 256 - 1); - if (fgets ((char *) buffer, 256, fp)) - { - unformat_input_t in; - unformat_init_string (&in, (char *) buffer, - strlen ((char *) buffer)); - if (unformat (&in, "%U", unformat_bitmap_list, &r) != 1) - clib_warning ("unformat_bitmap_list failed"); - unformat_free (&in); - } - vec_free (buffer); - fclose (fp); - } - return r; -} - /* Called early in the init sequence */ @@ -320,13 +286,13 @@ vlib_thread_init (vlib_main_t * vm) { uword c; /* *INDENT-OFF* */ - clib_bitmap_foreach (c, tr->coremask, ({ + clib_bitmap_foreach (c, tr->coremask) { if (clib_bitmap_get(avail_cpu, c) == 0) return clib_error_return (0, "cpu %u is not available to be used" " for the '%s' thread",c, tr->name); avail_cpu = clib_bitmap_set(avail_cpu, c, 0); - })); + } /* *INDENT-ON* */ } else @@ -581,7 +547,8 @@ vlib_worker_thread_bootstrap_fn (void *arg) __os_thread_index = w - vlib_worker_threads; - vlib_process_start_switch_stack (vlib_mains[__os_thread_index], 0); + vlib_process_start_switch_stack (vlib_get_main_by_index (__os_thread_index), + 0); rv = (void *) clib_calljmp ((uword (*)(uword)) w->thread_function, (uword) arg, w->thread_stack + VLIB_THREAD_STACK_SIZE); @@ -606,14 +573,14 @@ vlib_get_thread_core_numa (vlib_worker_thread_t * w, unsigned cpu_id) /* *INDENT-OFF* */ clib_sysfs_read ("/sys/devices/system/node/online", "%U", unformat_bitmap_list, &nbmp); - clib_bitmap_foreach (node, nbmp, ({ + clib_bitmap_foreach (node, nbmp) { p = format (p, "%s%u/cpulist%c", sys_node_path, node, 0); clib_sysfs_read ((char *) p, "%U", unformat_bitmap_list, &cbmp); if (clib_bitmap_get (cbmp, cpu_id)) numa_id = node; vec_reset_length (cbmp); vec_reset_length (p); - })); + } /* *INDENT-ON* */ vec_free (nbmp); vec_free (cbmp); @@ -640,8 +607,11 @@ vlib_launch_thread_int (void *fp, vlib_worker_thread_t * w, unsigned cpu_id) /* If the user requested a NUMA heap, create it... */ if (tm->numa_heap_size) { - numa_heap = clib_mem_init_thread_safe_numa - (0 /* DIY */ , tm->numa_heap_size, w->numa_id); + clib_mem_set_numa_affinity (w->numa_id, 1 /* force */ ); + numa_heap = clib_mem_create_heap (0 /* DIY */ , tm->numa_heap_size, + 1 /* is_locked */ , + "numa %u heap", w->numa_id); + clib_mem_set_default_numa_affinity (); mm->per_numa_mheaps[w->numa_id] = numa_heap; } else @@ -673,6 +643,7 @@ vlib_launch_thread_int (void *fp, vlib_worker_thread_t * w, unsigned cpu_id) static clib_error_t * start_workers (vlib_main_t * vm) { + vlib_global_main_t *vgm = vlib_get_global_main (); int i, j; vlib_worker_thread_t *w; vlib_main_t *vm_clone; @@ -682,14 +653,15 @@ start_workers (vlib_main_t * vm) vlib_node_runtime_t *rt; u32 n_vlib_mains = tm->n_vlib_mains; u32 worker_thread_index; - u8 *main_heap = clib_mem_get_per_cpu_heap (); + clib_mem_heap_t *main_heap = clib_mem_get_per_cpu_heap (); + vlib_stats_register_mem_heap (main_heap); vec_reset_length (vlib_worker_threads); /* Set up the main thread */ vec_add2_aligned (vlib_worker_threads, w, 1, CLIB_CACHE_LINE_BYTES); w->elog_track.name = "main thread"; - elog_track_register (&vm->elog_main, &w->elog_track); + elog_track_register (vlib_get_elog_main (), &w->elog_track); if (vec_len (tm->thread_prefix)) { @@ -697,23 +669,20 @@ start_workers (vlib_main_t * vm) vlib_set_thread_name ((char *) w->name); } - vm->elog_main.lock = + vgm->elog_main.lock = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES, CLIB_CACHE_LINE_BYTES); - vm->elog_main.lock[0] = 0; + vgm->elog_main.lock[0] = 0; clib_callback_data_init (&vm->vlib_node_runtime_perf_callbacks, &vm->worker_thread_main_loop_callback_lock); + vec_validate_aligned (vgm->vlib_mains, n_vlib_mains - 1, + CLIB_CACHE_LINE_BYTES); + _vec_len (vgm->vlib_mains) = 0; + vec_add1_aligned (vgm->vlib_mains, vm, CLIB_CACHE_LINE_BYTES); + if (n_vlib_mains > 1) { - /* Replace hand-crafted length-1 vector with a real vector */ - vlib_mains = 0; - - vec_validate_aligned (vlib_mains, tm->n_vlib_mains - 1, - CLIB_CACHE_LINE_BYTES); - _vec_len (vlib_mains) = 0; - vec_add1_aligned (vlib_mains, vm, CLIB_CACHE_LINE_BYTES); - vlib_worker_threads->wait_at_barrier = clib_mem_alloc_aligned (sizeof (u32), CLIB_CACHE_LINE_BYTES); vlib_worker_threads->workers_at_barrier = @@ -731,7 +700,7 @@ start_workers (vlib_main_t * vm) /* Without update or refork */ *vlib_worker_threads->node_reforks_required = 0; - vm->need_vlib_worker_thread_node_runtime_update = 0; + vgm->need_vlib_worker_thread_node_runtime_update = 0; /* init timing */ vm->barrier_epoch = 0; @@ -774,7 +743,7 @@ start_workers (vlib_main_t * vm) w->elog_track.name = (char *) format (0, "%s %d", tr->name, k + 1); vec_add1 (w->elog_track.name, 0); - elog_track_register (&vm->elog_main, &w->elog_track); + elog_track_register (vlib_get_elog_main (), &w->elog_track); if (tr->no_data_structure_clone) continue; @@ -784,14 +753,13 @@ start_workers (vlib_main_t * vm) vm_clone = clib_mem_alloc_aligned (sizeof (*vm_clone), CLIB_CACHE_LINE_BYTES); - clib_memcpy (vm_clone, vlib_mains[0], sizeof (*vm_clone)); + clib_memcpy (vm_clone, vlib_get_first_main (), + sizeof (*vm_clone)); vm_clone->thread_index = worker_thread_index; vm_clone->heap_base = w->thread_mheap; vm_clone->heap_aligned_base = (void *) (((uword) w->thread_mheap) & ~(VLIB_FRAME_ALIGN - 1)); - vm_clone->init_functions_called = - hash_create (0, /* value bytes */ 0); vm_clone->pending_rpc_requests = 0; vec_validate (vm_clone->pending_rpc_requests, 0); _vec_len (vm_clone->pending_rpc_requests) = 0; @@ -803,7 +771,7 @@ start_workers (vlib_main_t * vm) (&vm_clone->vlib_node_runtime_perf_callbacks, &vm_clone->worker_thread_main_loop_callback_lock); - nm = &vlib_mains[0]->node_main; + nm = &vlib_get_first_main ()->node_main; nm_clone = &vm_clone->node_main; /* fork next frames array, preserving node runtime indices */ nm_clone->next_frames = vec_dup_aligned (nm->next_frames, @@ -861,6 +829,9 @@ start_workers (vlib_main_t * vm) nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT] = vec_dup_aligned (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT], CLIB_CACHE_LINE_BYTES); + clib_interrupt_init ( + &nm_clone->interrupts, + vec_len (nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT])); vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT]) { vlib_node_t *n = vlib_get_node (vm, rt->node_index); @@ -900,18 +871,20 @@ start_workers (vlib_main_t * vm) /* Packet trace buffers are guaranteed to be empty, nothing to do here */ clib_mem_set_heap (oldheap); - vec_add1_aligned (vlib_mains, vm_clone, CLIB_CACHE_LINE_BYTES); + vec_add1_aligned (vgm->vlib_mains, vm_clone, + CLIB_CACHE_LINE_BYTES); /* Switch to the stats segment ... */ void *oldheap = vlib_stats_push_heap (0); - vm_clone->error_main.counters = vec_dup_aligned - (vlib_mains[0]->error_main.counters, CLIB_CACHE_LINE_BYTES); + vm_clone->error_main.counters = + vec_dup_aligned (vlib_get_first_main ()->error_main.counters, + CLIB_CACHE_LINE_BYTES); vlib_stats_pop_heap2 (vm_clone->error_main.counters, worker_thread_index, oldheap, 1); - vm_clone->error_main.counters_last_clear = vec_dup_aligned - (vlib_mains[0]->error_main.counters_last_clear, - CLIB_CACHE_LINE_BYTES); + vm_clone->error_main.counters_last_clear = vec_dup_aligned ( + vlib_get_first_main ()->error_main.counters_last_clear, + CLIB_CACHE_LINE_BYTES); worker_thread_index++; } @@ -945,7 +918,7 @@ start_workers (vlib_main_t * vm) (char *) format (0, "%s %d", tr->name, j + 1); w->registration = tr; vec_add1 (w->elog_track.name, 0); - elog_track_register (&vm->elog_main, &w->elog_track); + elog_track_register (vlib_get_elog_main (), &w->elog_track); } } } @@ -974,13 +947,13 @@ start_workers (vlib_main_t * vm) { uword c; /* *INDENT-OFF* */ - clib_bitmap_foreach (c, tr->coremask, ({ + clib_bitmap_foreach (c, tr->coremask) { w = vlib_worker_threads + worker_thread_index++; err = vlib_launch_thread_int (vlib_worker_thread_bootstrap_fn, w, c); if (err) clib_error_report (err); - })); + } /* *INDENT-ON* */ } } @@ -1000,15 +973,10 @@ worker_thread_node_runtime_update_internal (void) vlib_node_main_t *nm, *nm_clone; vlib_main_t *vm_clone; vlib_node_runtime_t *rt; - never_inline void - vlib_node_runtime_sync_stats (vlib_main_t * vm, - vlib_node_runtime_t * r, - uword n_calls, - uword n_vectors, uword n_clocks); ASSERT (vlib_get_thread_index () == 0); - vm = vlib_mains[0]; + vm = vlib_get_first_main (); nm = &vm->node_main; ASSERT (*vlib_worker_threads->wait_at_barrier == 1); @@ -1024,11 +992,11 @@ worker_thread_node_runtime_update_internal (void) vlib_node_sync_stats (vm, n); } - for (i = 1; i < vec_len (vlib_mains); i++) + for (i = 1; i < vlib_get_n_threads (); i++) { vlib_node_t *n; - vm_clone = vlib_mains[i]; + vm_clone = vlib_get_main_by_index (i); nm_clone = &vm_clone->node_main; for (j = 0; j < vec_len (nm_clone->nodes); j++) @@ -1056,7 +1024,7 @@ vlib_worker_thread_node_refork (void) int j; - vm = vlib_mains[0]; + vm = vlib_get_first_main (); nm = &vm->node_main; vm_clone = vlib_get_main (); nm_clone = &vm_clone->node_main; @@ -1134,6 +1102,7 @@ vlib_worker_thread_node_refork (void) /* keep previous node state */ new_n_clone->state = old_n_clone->state; + new_n_clone->flags = old_n_clone->flags; } vec_add1 (nm_clone->nodes, new_n_clone); new_n_clone++; @@ -1165,6 +1134,7 @@ vlib_worker_thread_node_refork (void) { rt = vlib_node_get_runtime (vm_clone, old_rt[j].node_index); rt->state = old_rt[j].state; + rt->flags = old_rt[j].flags; clib_memcpy_fast (rt->runtime_data, old_rt[j].runtime_data, VLIB_NODE_RUNTIME_DATA_SIZE); } @@ -1176,6 +1146,9 @@ vlib_worker_thread_node_refork (void) nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT] = vec_dup_aligned (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT], CLIB_CACHE_LINE_BYTES); + clib_interrupt_resize ( + &nm_clone->interrupts, + vec_len (nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT])); vec_foreach (rt, nm_clone->nodes_by_type[VLIB_NODE_TYPE_INPUT]) { @@ -1192,6 +1165,7 @@ vlib_worker_thread_node_refork (void) { rt = vlib_node_get_runtime (vm_clone, old_rt[j].node_index); rt->state = old_rt[j].state; + rt->flags = old_rt[j].flags; clib_memcpy_fast (rt->runtime_data, old_rt[j].runtime_data, VLIB_NODE_RUNTIME_DATA_SIZE); } @@ -1219,6 +1193,7 @@ vlib_worker_thread_node_refork (void) { rt = vlib_node_get_runtime (vm_clone, old_rt[j].node_index); rt->state = old_rt[j].state; + rt->flags = old_rt[j].flags; clib_memcpy_fast (rt->runtime_data, old_rt[j].runtime_data, VLIB_NODE_RUNTIME_DATA_SIZE); } @@ -1380,35 +1355,6 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input) VLIB_EARLY_CONFIG_FUNCTION (cpu_config, "cpu"); -void vnet_main_fixup (vlib_fork_fixup_t which) __attribute__ ((weak)); -void -vnet_main_fixup (vlib_fork_fixup_t which) -{ -} - -void -vlib_worker_thread_fork_fixup (vlib_fork_fixup_t which) -{ - vlib_main_t *vm = vlib_get_main (); - - if (vlib_mains == 0) - return; - - ASSERT (vlib_get_thread_index () == 0); - vlib_worker_thread_barrier_sync (vm); - - switch (which) - { - case VLIB_WORKER_THREAD_FORK_FIXUP_NEW_SW_IF_INDEX: - vnet_main_fixup (VLIB_WORKER_THREAD_FORK_FIXUP_NEW_SW_IF_INDEX); - break; - - default: - ASSERT (0); - } - vlib_worker_thread_barrier_release (vm); -} - /* * Enforce minimum open time to minimize packet loss due to Rx overflow, * based on a test based heuristic that barrier should be open for at least @@ -1429,7 +1375,7 @@ vlib_worker_thread_initial_barrier_sync_and_release (vlib_main_t * vm) { f64 deadline; f64 now = vlib_time_now (vm); - u32 count = vec_len (vlib_mains) - 1; + u32 count = vlib_get_n_threads () - 1; /* No worker threads? */ if (count == 0) @@ -1455,7 +1401,7 @@ vlib_worker_thread_initial_barrier_sync_and_release (vlib_main_t * vm) u8 vlib_worker_thread_barrier_held (void) { - if (vec_len (vlib_mains) < 2) + if (vlib_get_n_threads () < 2) return (1); return (*vlib_worker_threads->wait_at_barrier == 1); @@ -1473,13 +1419,13 @@ vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name) u32 count; int i; - if (vec_len (vlib_mains) < 2) + if (vlib_get_n_threads () < 2) return; ASSERT (vlib_get_thread_index () == 0); vlib_worker_threads[0].barrier_caller = func_name; - count = vec_len (vlib_mains) - 1; + count = vlib_get_n_threads () - 1; /* Record entry relative to last close */ now = vlib_time_now (vm); @@ -1501,10 +1447,12 @@ vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name) * the barrier hold-down timer. */ max_vector_rate = 0.0; - for (i = 1; i < vec_len (vlib_mains); i++) - max_vector_rate = - clib_max (max_vector_rate, - (f64) vlib_last_vectors_per_main_loop (vlib_mains[i])); + for (i = 1; i < vlib_get_n_threads (); i++) + { + vlib_main_t *ovm = vlib_get_main_by_index (i); + max_vector_rate = clib_max (max_vector_rate, + (f64) vlib_last_vectors_per_main_loop (ovm)); + } vlib_worker_threads[0].barrier_sync_count++; @@ -1558,6 +1506,7 @@ vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name) void vlib_worker_thread_barrier_release (vlib_main_t * vm) { + vlib_global_main_t *vgm = vlib_get_global_main (); f64 deadline; f64 now; f64 minimum_open; @@ -1566,7 +1515,7 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm) f64 t_update_main = 0.0; int refork_needed = 0; - if (vec_len (vlib_mains) < 2) + if (vlib_get_n_threads () < 2) return; ASSERT (vlib_get_thread_index () == 0); @@ -1582,7 +1531,7 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm) } /* Update (all) node runtimes before releasing the barrier, if needed */ - if (vm->need_vlib_worker_thread_node_runtime_update) + if (vgm->need_vlib_worker_thread_node_runtime_update) { /* * Lock stat segment here, so we's safe when @@ -1593,12 +1542,12 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm) /* Do stats elements on main thread */ worker_thread_node_runtime_update_internal (); - vm->need_vlib_worker_thread_node_runtime_update = 0; + vgm->need_vlib_worker_thread_node_runtime_update = 0; /* Do per thread rebuilds in parallel */ refork_needed = 1; clib_atomic_fetch_add (vlib_worker_threads->node_reforks_required, - (vec_len (vlib_mains) - 1)); + (vlib_get_n_threads () - 1)); now = vlib_time_now (vm); t_update_main = now - vm->barrier_epoch; } @@ -1670,9 +1619,10 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm) void vlib_worker_wait_one_loop (void) { + vlib_global_main_t *vgm = vlib_get_global_main (); ASSERT (vlib_get_thread_index () == 0); - if (vec_len (vlib_mains) < 2) + if (vlib_get_n_threads () < 2) return; if (vlib_worker_thread_barrier_held ()) @@ -1681,17 +1631,17 @@ vlib_worker_wait_one_loop (void) u32 *counts = 0; u32 ii; - vec_validate (counts, vec_len (vlib_mains) - 1); + vec_validate (counts, vlib_get_n_threads () - 1); /* record the current loop counts */ - vec_foreach_index (ii, vlib_mains) - counts[ii] = vlib_mains[ii]->main_loop_count; + vec_foreach_index (ii, vgm->vlib_mains) + counts[ii] = vgm->vlib_mains[ii]->main_loop_count; /* spin until each changes, apart from the main thread, or we'd be * a while */ for (ii = 1; ii < vec_len (counts); ii++) { - while (counts[ii] == vlib_mains[ii]->main_loop_count) + while (counts[ii] == vgm->vlib_mains[ii]->main_loop_count) CLIB_PAUSE (); } @@ -1699,148 +1649,10 @@ vlib_worker_wait_one_loop (void) return; } -/* - * Check the frame queue to see if any frames are available. - * If so, pull the packets off the frames and put them to - * the handoff node. - */ -int -vlib_frame_queue_dequeue (vlib_main_t * vm, vlib_frame_queue_main_t * fqm) -{ - u32 thread_id = vm->thread_index; - vlib_frame_queue_t *fq = fqm->vlib_frame_queues[thread_id]; - vlib_frame_queue_elt_t *elt; - u32 *from, *to; - vlib_frame_t *f; - int msg_type; - int processed = 0; - u32 n_left_to_node; - u32 vectors = 0; - - ASSERT (fq); - ASSERT (vm == vlib_mains[thread_id]); - - if (PREDICT_FALSE (fqm->node_index == ~0)) - return 0; - /* - * Gather trace data for frame queues - */ - if (PREDICT_FALSE (fq->trace)) - { - frame_queue_trace_t *fqt; - frame_queue_nelt_counter_t *fqh; - u32 elix; - - fqt = &fqm->frame_queue_traces[thread_id]; - - fqt->nelts = fq->nelts; - fqt->head = fq->head; - fqt->head_hint = fq->head_hint; - fqt->tail = fq->tail; - fqt->threshold = fq->vector_threshold; - fqt->n_in_use = fqt->tail - fqt->head; - if (fqt->n_in_use >= fqt->nelts) - { - // if beyond max then use max - fqt->n_in_use = fqt->nelts - 1; - } - - /* Record the number of elements in use in the histogram */ - fqh = &fqm->frame_queue_histogram[thread_id]; - fqh->count[fqt->n_in_use]++; - - /* Record a snapshot of the elements in use */ - for (elix = 0; elix < fqt->nelts; elix++) - { - elt = fq->elts + ((fq->head + 1 + elix) & (fq->nelts - 1)); - if (1 || elt->valid) - { - fqt->n_vectors[elix] = elt->n_vectors; - } - } - fqt->written = 1; - } - - while (1) - { - vlib_buffer_t *b; - if (fq->head == fq->tail) - { - fq->head_hint = fq->head; - return processed; - } - - elt = fq->elts + ((fq->head + 1) & (fq->nelts - 1)); - - if (!elt->valid) - { - fq->head_hint = fq->head; - return processed; - } - - from = elt->buffer_index; - msg_type = elt->msg_type; - - ASSERT (msg_type == VLIB_FRAME_QUEUE_ELT_DISPATCH_FRAME); - ASSERT (elt->n_vectors <= VLIB_FRAME_SIZE); - - f = vlib_get_frame_to_node (vm, fqm->node_index); - - /* If the first vector is traced, set the frame trace flag */ - b = vlib_get_buffer (vm, from[0]); - if (b->flags & VLIB_BUFFER_IS_TRACED) - f->frame_flags |= VLIB_NODE_FLAG_TRACE; - - to = vlib_frame_vector_args (f); - - n_left_to_node = elt->n_vectors; - - while (n_left_to_node >= 4) - { - to[0] = from[0]; - to[1] = from[1]; - to[2] = from[2]; - to[3] = from[3]; - to += 4; - from += 4; - n_left_to_node -= 4; - } - - while (n_left_to_node > 0) - { - to[0] = from[0]; - to++; - from++; - n_left_to_node--; - } - - vectors += elt->n_vectors; - f->n_vectors = elt->n_vectors; - vlib_put_frame_to_node (vm, fqm->node_index, f); - - elt->valid = 0; - elt->n_vectors = 0; - elt->msg_type = 0xfefefefe; - CLIB_MEMORY_BARRIER (); - fq->head++; - processed++; - - /* - * Limit the number of packets pushed into the graph - */ - if (vectors >= fq->vector_threshold) - { - fq->head_hint = fq->head; - return processed; - } - } - ASSERT (0); - return processed; -} - void vlib_worker_thread_fn (void *arg) { + vlib_global_main_t *vgm = vlib_get_global_main (); vlib_worker_thread_t *w = (vlib_worker_thread_t *) arg; vlib_thread_main_t *tm = vlib_get_thread_main (); vlib_main_t *vm = vlib_get_main (); @@ -1854,8 +1666,11 @@ vlib_worker_thread_fn (void *arg) clib_time_init (&vm->clib_time); clib_mem_set_heap (w->thread_mheap); - e = vlib_call_init_exit_functions_no_sort - (vm, &vm->worker_init_function_registrations, 1 /* call_once */ ); + vm->worker_init_functions_called = hash_create (0, 0); + + e = vlib_call_init_exit_functions_no_sort ( + vm, &vgm->worker_init_function_registrations, 1 /* call_once */, + 0 /* is_global */); if (e) clib_error_report (e); @@ -1977,24 +1792,24 @@ show_clock_command_fn (vlib_main_t * vm, verbose, format_clib_timebase_time, clib_timebase_now (tb)); - if (vec_len (vlib_mains) == 1) + if (vlib_get_n_threads () == 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++) + for (i = 1; i < vlib_get_n_threads (); i++) { - if (vlib_mains[i] == 0) + vlib_main_t *ovm = vlib_get_main_by_index (i); + if (ovm == 0) continue; - vlib_cli_output (vm, "%d: %U", i, format_clib_time, - &vlib_mains[i]->clib_time, verbose); + vlib_cli_output (vm, "%d: %U", i, format_clib_time, &ovm->clib_time, + verbose); - 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); + vlib_cli_output ( + vm, "Thread %d offset %.9f error %.9f", i, ovm->time_offset, + vm->time_last_barrier_release - ovm->time_last_barrier_release); } return 0; } @@ -2008,6 +1823,12 @@ VLIB_CLI_COMMAND (f_command, static) = }; /* *INDENT-ON* */ +vlib_thread_main_t * +vlib_get_thread_main_not_inline (void) +{ + return vlib_get_thread_main (); +} + /* * fd.io coding-style-patch-verification: ON *