diff options
author | Miklos Tirpak <miklos.tirpak@gmail.com> | 2021-01-12 15:14:02 +0100 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2021-02-04 09:56:54 +0000 |
commit | 38fae310843b7431136f40bfa8cf7c6bec59450f (patch) | |
tree | 6a45176f8a5782f23bc4a579a14d3ad3646e7d37 /src/vlib | |
parent | 15cb3dac874bcec701a33723467b81a53a6fc4d3 (diff) |
vlib: increase the stats epoch only when necessary
When the counter vectors are validated and they are already long enough
to fit the given index in memory, there is no need to increase the stats
segment epoch. In this case, the counter vectors do not change as a
result of the validation.
This optimization is necessary for the case when the configuration is
changed at multiple thousands per second rate. The counter vectors grow
at the beginning and their size stabilizes after a while. Without this
improvement, it can still take several seconds for a stats reader to
succeed.
Type: improvement
Signed-off-by: Miklos Tirpak <miklos.tirpak@gmail.com>
Change-Id: I5a6c30255832716a1460018d0bd0f63031de102b
Diffstat (limited to 'src/vlib')
-rw-r--r-- | src/vlib/counter.c | 51 | ||||
-rw-r--r-- | src/vlib/test/test_counters.py | 37 |
2 files changed, 72 insertions, 16 deletions
diff --git a/src/vlib/counter.c b/src/vlib/counter.c index 81c81aea02f..186b48d869e 100644 --- a/src/vlib/counter.c +++ b/src/vlib/counter.c @@ -79,15 +79,26 @@ void vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, u32 index) { vlib_thread_main_t *tm = vlib_get_thread_main (); - int i; + int i, resized = 0; void *oldheap = vlib_stats_push_heap (cm->counters); vec_validate (cm->counters, tm->n_vlib_mains - 1); for (i = 0; i < tm->n_vlib_mains; i++) - vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES); - - vlib_stats_pop_heap (cm, oldheap, index, - 2 /* STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE */ ); + if (index >= vec_len (cm->counters[i])) + { + if (vec_resize_will_expand (cm->counters[i], + index - vec_len (cm->counters[i]) + + 1 /* length_increment */)) + resized++; + vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES); + } + + /* Avoid the epoch increase when there was no counter vector resize. */ + if (resized) + vlib_stats_pop_heap (cm, oldheap, index, + 2 /* STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE */); + else + clib_mem_set_heap (oldheap); } void @@ -108,15 +119,26 @@ void vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index) { vlib_thread_main_t *tm = vlib_get_thread_main (); - int i; + int i, resized = 0; void *oldheap = vlib_stats_push_heap (cm->counters); vec_validate (cm->counters, tm->n_vlib_mains - 1); for (i = 0; i < tm->n_vlib_mains; i++) - vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES); - - vlib_stats_pop_heap (cm, oldheap, index, - 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); + if (index >= vec_len (cm->counters[i])) + { + if (vec_resize_will_expand (cm->counters[i], + index - vec_len (cm->counters[i]) + + 1 /* length_increment */)) + resized++; + vec_validate_aligned (cm->counters[i], index, CLIB_CACHE_LINE_BYTES); + } + + /* Avoid the epoch increase when there was no counter vector resize. */ + if (resized) + vlib_stats_pop_heap (cm, oldheap, index, + 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */); + else + clib_mem_set_heap (oldheap); } int @@ -130,8 +152,7 @@ int /* 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 */ ); + clib_mem_set_heap (oldheap); return 1; } @@ -144,13 +165,11 @@ int index - vec_len (cm->counters[i]) + 1 /* length_increment */)) { - vlib_stats_pop_heap (cm, oldheap, index, - 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); + clib_mem_set_heap (oldheap); return 1; } } - vlib_stats_pop_heap (cm, oldheap, index, - 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); + clib_mem_set_heap (oldheap); return 0; } diff --git a/src/vlib/test/test_counters.py b/src/vlib/test/test_counters.py new file mode 100644 index 00000000000..5c63308fcb0 --- /dev/null +++ b/src/vlib/test/test_counters.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +from framework import VppTestCase + + +class TestCounters(VppTestCase): + """ Counters C Unit Tests """ + + @classmethod + def setUpClass(cls): + super(TestCounters, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestCounters, cls).tearDownClass() + + def setUp(self): + super(TestCounters, self).setUp() + + def tearDown(self): + super(TestCounters, self).tearDown() + + def test_counter_simple_expand(self): + """ Simple Counter Expand """ + error = self.vapi.cli("test counter simple expand") + + if error: + self.logger.critical(error) + self.assertNotIn('failed', error) + + def test_counter_combined_expand(self): + """ Combined Counter Expand """ + error = self.vapi.cli("test counter combined expand") + + if error: + self.logger.critical(error) + self.assertNotIn('failed', error) |