diff options
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/error.c | 130 | ||||
-rw-r--r-- | src/vlib/error.h | 4 | ||||
-rw-r--r-- | src/vlib/stats/cli.c | 4 | ||||
-rw-r--r-- | src/vlib/stats/shared.h | 2 | ||||
-rw-r--r-- | src/vlib/stats/stats.c | 58 | ||||
-rw-r--r-- | src/vlib/stats/stats.h | 4 | ||||
-rw-r--r-- | src/vlib/threads.c | 26 |
7 files changed, 85 insertions, 143 deletions
diff --git a/src/vlib/error.c b/src/vlib/error.c index e513a7d673b..f01e0b63e95 100644 --- a/src/vlib/error.c +++ b/src/vlib/error.c @@ -112,6 +112,17 @@ vlib_error_drop_buffers (vlib_main_t * vm, return n_buffers; } +static u8 * +format_stats_counter_name (u8 *s, va_list *va) +{ + u8 *id = va_arg (*va, u8 *); + + for (u32 i = 0; id[i] != 0; i++) + vec_add1 (s, id[i] == ' ' ? ' ' : id[i]); + + return s; +} + /* Reserves given number of error codes for given node. */ void vlib_register_errors (vlib_main_t *vm, u32 node_index, u32 n_errors, @@ -119,92 +130,93 @@ vlib_register_errors (vlib_main_t *vm, u32 node_index, u32 n_errors, { vlib_error_main_t *em = &vm->error_main; vlib_node_main_t *nm = &vm->node_main; - vlib_node_t *n = vlib_get_node (vm, node_index); + vlib_error_desc_t *cd; + u32 n_threads = vlib_get_n_threads (); + elog_event_type_t t = {}; uword l; - void *oldheap; + u64 **sc; ASSERT (vlib_get_thread_index () == 0); + vlib_stats_segment_lock (); + /* Free up any previous error strings. */ if (n->n_errors > 0) - heap_dealloc (em->counters_heap, n->error_heap_handle); + { + cd = vec_elt_at_index (em->counters_heap, n->error_heap_index); + for (u32 i = 0; i < n->n_errors; i++) + vlib_stats_remove_entry (cd[i].stats_entry_index); + heap_dealloc (em->counters_heap, n->error_heap_handle); + } n->n_errors = n_errors; n->error_counters = counters; if (n_errors == 0) - return; + goto done; + + n->error_heap_index = + heap_alloc (em->counters_heap, n_errors, n->error_heap_handle); + l = vec_len (em->counters_heap); + cd = vec_elt_at_index (em->counters_heap, n->error_heap_index); /* Legacy node */ if (!counters) { - counters = clib_mem_alloc (sizeof (counters[0]) * n_errors); - int i; - for (i = 0; i < n_errors; i++) + for (int i = 0; i < n_errors; i++) { - counters[i].name = error_strings[i]; - counters[i].desc = error_strings[i]; - counters[i].severity = VL_COUNTER_SEVERITY_ERROR; + cd[i].name = error_strings[i]; + cd[i].desc = error_strings[i]; + cd[i].severity = VL_COUNTER_SEVERITY_ERROR; } } - - n->error_heap_index = - heap_alloc (em->counters_heap, n_errors, n->error_heap_handle); - l = vec_len (em->counters_heap); - clib_memcpy (vec_elt_at_index (em->counters_heap, n->error_heap_index), - counters, n_errors * sizeof (counters[0])); + else + clib_memcpy (cd, counters, n_errors * sizeof (counters[0])); vec_validate (vm->error_elog_event_types, l - 1); - /* Switch to the stats segment ... */ - oldheap = vlib_stats_set_heap (); + if (em->stats_err_entry_index == 0) + em->stats_err_entry_index = vlib_stats_add_counter_vector ("/node/errors"); - /* Allocate a counter/elog type for each error. */ - vec_validate (em->counters, l - 1); + ASSERT (em->stats_err_entry_index != 0 && em->stats_err_entry_index != ~0); - /* Zero counters for re-registrations of errors. */ - if (n->error_heap_index + n_errors <= vec_len (em->counters_last_clear)) - clib_memcpy (em->counters + n->error_heap_index, - em->counters_last_clear + n->error_heap_index, - n_errors * sizeof (em->counters[0])); - else - clib_memset (em->counters + n->error_heap_index, - 0, n_errors * sizeof (em->counters[0])); + vlib_stats_validate (em->stats_err_entry_index, n_threads - 1, l - 1); + sc = vlib_stats_get_entry_data_pointer (em->stats_err_entry_index); - oldheap = clib_mem_set_heap (oldheap); + for (int i = 0; i < n_threads; i++) + { + vlib_main_t *tvm = vlib_get_main_by_index (i); + vlib_error_main_t *tem = &tvm->error_main; + tem->counters = sc[i]; + + /* Zero counters for re-registrations of errors. */ + if (n->error_heap_index + n_errors <= vec_len (tem->counters_last_clear)) + clib_memcpy (tem->counters + n->error_heap_index, + tem->counters_last_clear + n->error_heap_index, + n_errors * sizeof (tem->counters[0])); + else + clib_memset (tem->counters + n->error_heap_index, 0, + n_errors * sizeof (tem->counters[0])); + } /* Register counter indices in the stat segment directory */ - { - int i; - - for (i = 0; i < n_errors; i++) - { - vlib_stats_register_error_index (em->counters, n->error_heap_index + i, - "/err/%v/%s", n->name, - counters[i].name); - } - - } - - /* (re)register the em->counters base address, switch back to main heap */ - vlib_stats_update_error_vector (em->counters, vm->thread_index, 1); - - { - elog_event_type_t t; - uword i; - - clib_memset (&t, 0, sizeof (t)); - if (n_errors > 0) - vec_validate (nm->node_by_error, n->error_heap_index + n_errors - 1); - for (i = 0; i < n_errors; i++) - { - t.format = (char *) format (0, "%v %s: %%d", - n->name, counters[i].name); - vm->error_elog_event_types[n->error_heap_index + i] = t; - nm->node_by_error[n->error_heap_index + i] = n->index; - } - } + for (int i = 0; i < n_errors; i++) + cd[i].stats_entry_index = vlib_stats_add_symlink ( + em->stats_err_entry_index, n->error_heap_index + i, "/err/%v/%U", + n->name, format_stats_counter_name, cd[i].name); + + vec_validate (nm->node_by_error, n->error_heap_index + n_errors - 1); + + for (u32 i = 0; i < n_errors; i++) + { + t.format = (char *) format (0, "%v %s: %%d", n->name, cd[i].name); + vm->error_elog_event_types[n->error_heap_index + i] = t; + nm->node_by_error[n->error_heap_index + i] = n->index; + } + +done: + vlib_stats_segment_unlock (); } uword diff --git a/src/vlib/error.h b/src/vlib/error.h index b921067ee84..c7e7ce49269 100644 --- a/src/vlib/error.h +++ b/src/vlib/error.h @@ -56,6 +56,7 @@ typedef struct char *name; char *desc; enum vl_counter_severity_e severity; + u32 stats_entry_index; } vlib_error_desc_t; typedef struct @@ -69,6 +70,9 @@ typedef struct /* Counter structures in heap. Heap index indexes counter vector. */ vlib_error_desc_t *counters_heap; + + /* stats segment entry index */ + u32 stats_err_entry_index; } vlib_error_main_t; /* Per node error registration. */ diff --git a/src/vlib/stats/cli.c b/src/vlib/stats/cli.c index 4d7026b5995..94a852ac751 100644 --- a/src/vlib/stats/cli.c +++ b/src/vlib/stats/cli.c @@ -34,10 +34,6 @@ format_stat_dir_entry (u8 *s, va_list *args) type_name = "CMainPtr"; break; - case STAT_DIR_TYPE_ERROR_INDEX: - type_name = "ErrIndex"; - break; - case STAT_DIR_TYPE_NAME_VECTOR: type_name = "NameVector"; break; diff --git a/src/vlib/stats/shared.h b/src/vlib/stats/shared.h index d2d5d49cc54..8e44ce3dc86 100644 --- a/src/vlib/stats/shared.h +++ b/src/vlib/stats/shared.h @@ -11,7 +11,6 @@ typedef enum STAT_DIR_TYPE_SCALAR_INDEX, STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE, STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED, - STAT_DIR_TYPE_ERROR_INDEX, STAT_DIR_TYPE_NAME_VECTOR, STAT_DIR_TYPE_EMPTY, STAT_DIR_TYPE_SYMLINK, @@ -46,7 +45,6 @@ typedef struct volatile uint64_t epoch; volatile uint64_t in_progress; volatile vlib_stats_entry_t *directory_vector; - volatile uint64_t **error_vector; } vlib_stats_shared_header_t; #endif /* included_stat_segment_shared_h */ diff --git a/src/vlib/stats/stats.c b/src/vlib/stats/stats.c index 61f620469b1..9063fa375e6 100644 --- a/src/vlib/stats/stats.c +++ b/src/vlib/stats/stats.c @@ -244,64 +244,6 @@ vlib_stats_add_gauge (char *fmt, ...) } void -vlib_stats_register_error_index (u64 *em_vec, u64 index, char *fmt, ...) -{ - vlib_stats_segment_t *sm = vlib_stats_get_segment (); - vlib_stats_shared_header_t *shared_header = sm->shared_header; - vlib_stats_entry_t e = {}; - va_list va; - u8 *name; - - va_start (va, fmt); - name = va_format (0, fmt, &va); - va_end (va); - - ASSERT (shared_header); - - vlib_stats_segment_lock (); - u32 vector_index = vlib_stats_find_entry_index ("%v", name); - - if (vector_index == STAT_SEGMENT_INDEX_INVALID) - { - vec_add1 (name, 0); - vlib_stats_set_entry_name (&e, (char *) name); - e.type = STAT_DIR_TYPE_ERROR_INDEX; - e.index = index; - vector_index = vlib_stats_create_counter (&e); - - /* Warn clients to refresh any pointers they might be holding */ - shared_header->directory_vector = sm->directory_vector; - } - - vlib_stats_segment_unlock (); - vec_free (name); -} - -void -vlib_stats_update_error_vector (u64 *error_vector, u32 thread_index, int lock) -{ - vlib_stats_segment_t *sm = vlib_stats_get_segment (); - vlib_stats_shared_header_t *shared_header = sm->shared_header; - void *oldheap = clib_mem_set_heap (sm->heap); - - ASSERT (shared_header); - - if (lock) - vlib_stats_segment_lock (); - - /* Reset the client hash table pointer, since it WILL change! */ - vec_validate (sm->error_vector, thread_index); - sm->error_vector[thread_index] = error_vector; - - shared_header->error_vector = sm->error_vector; - shared_header->directory_vector = sm->directory_vector; - - if (lock) - vlib_stats_segment_unlock (); - clib_mem_set_heap (oldheap); -} - -void vlib_stats_set_gauge (u32 index, u64 value) { vlib_stats_segment_t *sm = vlib_stats_get_segment (); diff --git a/src/vlib/stats/stats.h b/src/vlib/stats/stats.h index 6db93719a0c..ef43510b255 100644 --- a/src/vlib/stats/stats.h +++ b/src/vlib/stats/stats.h @@ -75,7 +75,6 @@ typedef struct /* statistics segment */ uword *directory_vector_by_name; vlib_stats_entry_t *directory_vector; - volatile u64 **error_vector; u8 **nodes; /* Update interval */ @@ -129,9 +128,6 @@ vlib_stats_get_entry_data_pointer (u32 entry_index) clib_error_t *vlib_stats_init (vlib_main_t *vm); void *vlib_stats_set_heap (); -void vlib_stats_register_error_index (u64 *em_vec, u64 index, char *fmt, ...); -void vlib_stats_update_error_vector (u64 *error_vector, u32 thread_index, - int lock); void vlib_stats_segment_lock (void); void vlib_stats_segment_unlock (void); void vlib_stats_register_mem_heap (clib_mem_heap_t *); diff --git a/src/vlib/threads.c b/src/vlib/threads.c index 4dba08047c2..b470976d3d3 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -522,6 +522,7 @@ static clib_error_t * start_workers (vlib_main_t * vm) { vlib_global_main_t *vgm = vlib_get_global_main (); + vlib_main_t *fvm = vlib_get_first_main (); int i, j; vlib_worker_thread_t *w; vlib_main_t *vm_clone; @@ -531,6 +532,7 @@ start_workers (vlib_main_t * vm) vlib_node_runtime_t *rt; u32 n_vlib_mains = tm->n_vlib_mains; u32 worker_thread_index; + u32 stats_err_entry_index = fvm->error_main.stats_err_entry_index; clib_mem_heap_t *main_heap = clib_mem_get_per_cpu_heap (); vlib_stats_register_mem_heap (main_heap); @@ -600,6 +602,7 @@ start_workers (vlib_main_t * vm) for (k = 0; k < tr->count; k++) { vlib_node_t *n; + u64 **c; vec_add2 (vlib_worker_threads, w, 1); /* Currently unused, may not really work */ @@ -748,13 +751,10 @@ start_workers (vlib_main_t * vm) CLIB_CACHE_LINE_BYTES); /* Switch to the stats segment ... */ - void *oldheap = vlib_stats_set_heap (); - vm_clone->error_main.counters = - vec_dup_aligned (vlib_get_first_main ()->error_main.counters, - CLIB_CACHE_LINE_BYTES); - clib_mem_set_heap (oldheap); - vlib_stats_update_error_vector (vm_clone->error_main.counters, - worker_thread_index, 1); + vlib_stats_validate (stats_err_entry_index, worker_thread_index, + vec_len (fvm->error_main.counters) - 1); + c = vlib_stats_get_entry_data_pointer (stats_err_entry_index); + vm_clone->error_main.counters = c[worker_thread_index]; vm_clone->error_main.counters_last_clear = vec_dup_aligned ( vlib_get_first_main ()->error_main.counters_last_clear, @@ -893,6 +893,7 @@ vlib_worker_thread_node_refork (void) vlib_node_main_t *nm, *nm_clone; vlib_node_t **old_nodes_clone; vlib_node_runtime_t *rt, *old_rt; + u64 **c; vlib_node_t *new_n_clone; @@ -904,25 +905,18 @@ vlib_worker_thread_node_refork (void) nm_clone = &vm_clone->node_main; /* Re-clone error heap */ - u64 *old_counters = vm_clone->error_main.counters; u64 *old_counters_all_clear = vm_clone->error_main.counters_last_clear; clib_memcpy_fast (&vm_clone->error_main, &vm->error_main, sizeof (vm->error_main)); j = vec_len (vm->error_main.counters) - 1; - /* Switch to the stats segment ... */ - void *oldheap = vlib_stats_set_heap (); - vec_validate_aligned (old_counters, j, CLIB_CACHE_LINE_BYTES); - clib_mem_set_heap (oldheap); - vm_clone->error_main.counters = old_counters; - vlib_stats_update_error_vector (vm_clone->error_main.counters, - vm_clone->thread_index, 0); + c = vlib_stats_get_entry_data_pointer (vm->error_main.stats_err_entry_index); + vm_clone->error_main.counters = c[vm_clone->thread_index]; vec_validate_aligned (old_counters_all_clear, j, CLIB_CACHE_LINE_BYTES); vm_clone->error_main.counters_last_clear = old_counters_all_clear; - nm_clone = &vm_clone->node_main; vec_free (nm_clone->next_frames); nm_clone->next_frames = vec_dup_aligned (nm->next_frames, CLIB_CACHE_LINE_BYTES); |