diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vlib/buffer.c | 88 | ||||
-rw-r--r-- | src/vlib/main.c | 6 | ||||
-rw-r--r-- | src/vpp/stats/stat_segment.c | 47 | ||||
-rw-r--r-- | src/vpp/stats/stat_segment.h | 8 |
4 files changed, 138 insertions, 11 deletions
diff --git a/src/vlib/buffer.c b/src/vlib/buffer.c index c44d8e49d40..091799b3f12 100644 --- a/src/vlib/buffer.c +++ b/src/vlib/buffer.c @@ -46,6 +46,7 @@ #include <vppinfra/linux/sysfs.h> #include <vlib/vlib.h> #include <vlib/unix/unix.h> +#include <vpp/stats/stat_segment.h> #define VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA 16384 #define VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA_UNPRIV 8192 @@ -709,13 +710,84 @@ vlib_buffer_main_alloc (vlib_main_t * vm) bm->default_data_size = VLIB_BUFFER_DEFAULT_DATA_SIZE; } +static u32 +buffer_get_cached (vlib_buffer_pool_t * bp) +{ + u32 cached = 0; + vlib_buffer_pool_thread_t *bpt; + + /* *INDENT-OFF* */ + vec_foreach (bpt, bp->threads) + cached += vec_len (bpt->cached_buffers); + /* *INDENT-ON* */ + + return cached; +} + +static vlib_buffer_pool_t * +buffer_get_by_name (vlib_buffer_main_t * bm, char *name) +{ + vlib_buffer_pool_t *bp; + vec_foreach (bp, bm->buffer_pools) + { + if (!strcmp ((char *) bp->name, name)) + return bp; + } + + return 0; +} + +static void +buffer_gauges_update_used_fn (stat_segment_directory_entry_t * e) +{ + vlib_main_t *vm = vlib_get_main (); + vlib_buffer_pool_t *bp; + + bp = buffer_get_by_name (vm->buffer_main, + &e->name[sizeof ("/buffer/used/") - 1]); + if (!bp) + return; + + e->value = bp->n_buffers - vec_len (bp->buffers) - buffer_get_cached (bp); +} + +static void +buffer_gauges_update_available_fn (stat_segment_directory_entry_t * e) +{ + vlib_main_t *vm = vlib_get_main (); + vlib_buffer_pool_t *bp; + + bp = buffer_get_by_name (vm->buffer_main, + &e->name[sizeof ("/buffer/available/") - 1]); + if (!bp) + return; + + e->value = vec_len (bp->buffers); +} + +static void +buffer_gauges_update_cached_fn (stat_segment_directory_entry_t * e) +{ + vlib_main_t *vm = vlib_get_main (); + vlib_buffer_pool_t *bp; + + bp = buffer_get_by_name (vm->buffer_main, + &e->name[sizeof ("/buffer/cached/") - 1]); + if (!bp) + return; + + e->value = buffer_get_cached (bp); +} + clib_error_t * -vlib_buffer_main_init (struct vlib_main_t *vm) +vlib_buffer_main_init (struct vlib_main_t * vm) { vlib_buffer_main_t *bm; clib_error_t *err; clib_bitmap_t *bmp = 0; u32 numa_node; + vlib_buffer_pool_t *bp; + u8 *name; vlib_buffer_main_alloc (vm); @@ -743,6 +815,20 @@ vlib_buffer_main_init (struct vlib_main_t *vm) bm->n_numa_nodes = clib_bitmap_last_set (bmp) + 1; + vec_foreach (bp, bm->buffer_pools) + { + name = format (0, "/buffer/cached/%s%c", bp->name, 0); + stat_segment_register_gauge (name, buffer_gauges_update_cached_fn); + vec_free (name); + name = format (0, "/buffer/used/%s%c", bp->name, 0); + stat_segment_register_gauge (name, buffer_gauges_update_used_fn); + vec_free (name); + name = format (0, "/buffer/available/%s%c", bp->name, 0); + stat_segment_register_gauge (name, buffer_gauges_update_available_fn); + vec_free (name); + } + + done: vec_free (bmp); return err; diff --git a/src/vlib/main.c b/src/vlib/main.c index 89202beaa42..552e693aaf6 100644 --- a/src/vlib/main.c +++ b/src/vlib/main.c @@ -1979,19 +1979,19 @@ vlib_main (vlib_main_t * volatile vm, unformat_input_t * input) goto done; } - if ((error = vlib_buffer_main_init (vm))) + if ((error = vlib_map_stat_segment_init (vm))) { clib_error_report (error); goto done; } - if ((error = vlib_thread_init (vm))) + if ((error = vlib_buffer_main_init (vm))) { clib_error_report (error); goto done; } - if ((error = vlib_map_stat_segment_init (vm))) + if ((error = vlib_thread_init (vm))) { clib_error_report (error); goto done; diff --git a/src/vpp/stats/stat_segment.c b/src/vpp/stats/stat_segment.c index 793936bf08f..2d6c8c67901 100644 --- a/src/vpp/stats/stat_segment.c +++ b/src/vpp/stats/stat_segment.c @@ -214,15 +214,8 @@ vlib_map_stat_segment_init (void) stat_segment_main_t *sm = &stat_segment_main; stat_segment_shared_header_t *shared_header; stat_segment_directory_entry_t *ep; - - f64 *scalar_data; - u8 *name; void *oldheap; - u32 *lock; - int rv; ssize_t memory_size; - - int mfd; char *mem_name = "stat_segment_test"; void *memaddr; @@ -282,6 +275,7 @@ vlib_map_stat_segment_init (void) /* Save the vector offset in the shared segment, for clients */ shared_header->directory_offset = stat_segment_offset (shared_header, sm->directory_vector); + sm->gauges_fns = 0; clib_mem_set_heap (oldheap); @@ -514,6 +508,12 @@ do_stat_segment_updates (stat_segment_main_t * sm) if (sm->node_counters_enabled) update_node_counters (sm); + for (i = 0; i < vec_len (sm->gauges_fns); i++) + { + if (sm->gauges_fns[i]) + sm->gauges_fns[i] (&sm->directory_vector[i]); + } + /* Heartbeat, so clients detect we're still here */ sm->directory_vector[STAT_COUNTER_HEARTBEAT].value++; } @@ -618,6 +618,39 @@ statseg_init (vlib_main_t * vm) return 0; } +clib_error_t * +stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn) +{ + stat_segment_main_t *sm = &stat_segment_main; + stat_segment_shared_header_t *shared_header = sm->shared_header; + void *oldheap; + stat_segment_directory_entry_t e; + u32 index; + + ASSERT (shared_header); + + oldheap = vlib_stats_push_heap (); + vlib_stat_segment_lock (); + + memset (&e, 0, sizeof (e)); + e.type = STAT_DIR_TYPE_SCALAR_INDEX; + + memcpy (e.name, name, vec_len (name)); + index = vec_len (sm->directory_vector); + vec_add1 (sm->directory_vector, e); + + shared_header->directory_offset = + stat_segment_offset (shared_header, sm->directory_vector); + + vlib_stat_segment_unlock (); + clib_mem_set_heap (oldheap); + + vec_validate (sm->gauges_fns, index); + sm->gauges_fns[index] = update_fn; + + return NULL; +} + static clib_error_t * statseg_config (vlib_main_t * vm, unformat_input_t * input) { diff --git a/src/vpp/stats/stat_segment.h b/src/vpp/stats/stat_segment.h index 3ce82809255..f3ea50c9d99 100644 --- a/src/vpp/stats/stat_segment.h +++ b/src/vpp/stats/stat_segment.h @@ -85,8 +85,13 @@ stat_segment_pointer (void *start, uint64_t offset) return ((char *) start + offset); } +typedef void (*stat_segment_update_fn)(stat_segment_directory_entry_t * e); + typedef struct { + /* internal, does not point to shared memory */ + stat_segment_update_fn *gauges_fns; + /* statistics segment */ uword *directory_vector_by_name; stat_segment_directory_entry_t *directory_vector; @@ -104,4 +109,7 @@ typedef struct extern stat_segment_main_t stat_segment_main; +clib_error_t * +stat_segment_register_gauge (u8 *names, stat_segment_update_fn update_fn); + #endif |