summaryrefslogtreecommitdiffstats
path: root/src/vlib/counter.c
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2020-06-03 08:05:15 -0400
committerFlorin Coras <florin.coras@gmail.com>2020-06-04 14:42:26 +0000
commit8341f76fd1cd4351961cd8161cfed2814fc55103 (patch)
tree420010b919dacc54dde85e9f5d5b6fc305775aa2 /src/vlib/counter.c
parentc39c79c5aa7b5410f3aad4a770a741ab04f7dcc5 (diff)
fib: add barrier sync, pool/vector expand cases
load_balance_alloc_i(...) is not thread safe when the load_balance_pool or combined counter vectors expand. Type: fix Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: I7f295ed77350d1df0434d5ff461eedafe79131de
Diffstat (limited to 'src/vlib/counter.c')
-rw-r--r--src/vlib/counter.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/vlib/counter.c b/src/vlib/counter.c
index edba3754da4..adf667f4051 100644
--- a/src/vlib/counter.c
+++ b/src/vlib/counter.c
@@ -119,6 +119,44 @@ vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index)
3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ );
}
+int
+ vlib_validate_combined_counter_will_expand
+ (vlib_combined_counter_main_t * cm, u32 index)
+{
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+ int i;
+ void *oldheap = vlib_stats_push_heap (cm->counters);
+
+ /* Possibly once in recorded history */
+ if (PREDICT_FALSE (vec_len (cm->counters) == 0))
+ {
+ vlib_stats_pop_heap (cm, oldheap, index,
+ 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ );
+ return 1;
+ }
+
+ for (i = 0; i < tm->n_vlib_mains; i++)
+ {
+ /* Trivially OK, and proves that index >= vec_len(...) */
+ if (index < vec_len (cm->counters[i]))
+ continue;
+ if (_vec_resize_will_expand
+ (cm->counters[i],
+ index - vec_len (cm->counters[i]) /* length_increment */ ,
+ sizeof (cm->counters[i]) /* data_bytes */ ,
+ 0 /* header_bytes */ ,
+ CLIB_CACHE_LINE_BYTES /* data_alignment */ ))
+ {
+ vlib_stats_pop_heap (cm, oldheap, index,
+ 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ );
+ return 1;
+ }
+ }
+ vlib_stats_pop_heap (cm, oldheap, index,
+ 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ );
+ return 0;
+}
+
void
vlib_free_combined_counter (vlib_combined_counter_main_t * cm)
{