diff options
author | Damjan Marion <damarion@cisco.com> | 2022-03-14 13:04:38 +0100 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2022-03-14 18:33:32 +0000 |
commit | d1bd9af16ed6575e08871d1cadd429f2d5925220 (patch) | |
tree | 24698c66736780d0e2a8c6d5e8526ca1dd43b467 | |
parent | 85a9c101bffe99da141b496f95966258b922a440 (diff) |
stats: support recursive locking
Type: improvement
Change-Id: I85dd3d34bcb175dd68dda34a58cd454848a0fc2b
Signed-off-by: Damjan Marion <damarion@cisco.com>
-rw-r--r-- | src/vlib/stats/init.c | 2 | ||||
-rw-r--r-- | src/vlib/stats/stats.c | 33 | ||||
-rw-r--r-- | src/vlib/stats/stats.h | 2 |
3 files changed, 32 insertions, 5 deletions
diff --git a/src/vlib/stats/init.c b/src/vlib/stats/init.c index d81916a288d..d24c1580a88 100644 --- a/src/vlib/stats/init.c +++ b/src/vlib/stats/init.c @@ -88,6 +88,8 @@ vlib_stats_init (vlib_main_t *vm) shared_header->base = memaddr; sm->stat_segment_lockp = clib_mem_alloc (sizeof (clib_spinlock_t)); + sm->locking_thread_index = ~0; + sm->n_locks = 0; clib_spinlock_init (sm->stat_segment_lockp); oldheap = clib_mem_set_heap (sm->heap); diff --git a/src/vlib/stats/stats.c b/src/vlib/stats/stats.c index 19edaf0866d..97f84006eaf 100644 --- a/src/vlib/stats/stats.c +++ b/src/vlib/stats/stats.c @@ -7,24 +7,47 @@ vlib_stats_main_t vlib_stats_main; -/* - * Used only by VPP writers - */ - void vlib_stats_segment_lock (void) { + vlib_main_t *vm = vlib_get_main (); vlib_stats_segment_t *sm = vlib_stats_get_segment (); + + /* already locked by us */ + if (sm->shared_header->in_progress && + vm->thread_index == sm->locking_thread_index) + goto done; + + ASSERT (sm->locking_thread_index == ~0); + ASSERT (sm->shared_header->in_progress == 0); + ASSERT (sm->n_locks == 0); + clib_spinlock_lock (sm->stat_segment_lockp); + sm->shared_header->in_progress = 1; + sm->locking_thread_index = vm->thread_index; +done: + sm->n_locks++; } void vlib_stats_segment_unlock (void) { + vlib_main_t *vm = vlib_get_main (); vlib_stats_segment_t *sm = vlib_stats_get_segment (); + + ASSERT (sm->shared_header->in_progress == 1); + ASSERT (sm->locking_thread_index == vm->thread_index); + ASSERT (sm->n_locks > 0); + + sm->n_locks--; + + if (sm->n_locks > 0) + return; + sm->shared_header->epoch++; - sm->shared_header->in_progress = 0; + __atomic_store_n (&sm->shared_header->in_progress, 0, __ATOMIC_RELEASE); + sm->locking_thread_index = ~0; clib_spinlock_unlock (sm->stat_segment_lockp); } diff --git a/src/vlib/stats/stats.h b/src/vlib/stats/stats.h index 25d7c4ba484..faaa37a7ec2 100644 --- a/src/vlib/stats/stats.h +++ b/src/vlib/stats/stats.h @@ -82,6 +82,8 @@ typedef struct f64 update_interval; clib_spinlock_t *stat_segment_lockp; + u32 locking_thread_index; + u32 n_locks; clib_socket_t *socket; u8 *socket_name; ssize_t memory_size; |