diff options
Diffstat (limited to 'src/plugins/perfmon/perfmon.c')
-rw-r--r-- | src/plugins/perfmon/perfmon.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/src/plugins/perfmon/perfmon.c b/src/plugins/perfmon/perfmon.c index 411a07dea30..15690361a7f 100644 --- a/src/plugins/perfmon/perfmon.c +++ b/src/plugins/perfmon/perfmon.c @@ -325,10 +325,36 @@ perfmon_stop (vlib_main_t *vm) } static_always_inline u8 +is_enough_counters (perfmon_bundle_t *b) +{ + struct + { + u8 general; + u8 fixed; + } bl = { 0, 0 }, cpu = { 0, 0 }; + + /* how many does this uarch support */ + if (!clib_get_pmu_counter_count (&cpu.fixed, &cpu.general)) + return 0; + + /* how many does the bundle require */ + for (u16 i = 0; i < b->n_events; i++) + if (b->src->is_fixed && b->src->is_fixed (b->events[i])) + bl.fixed++; + else + bl.general++; + + return cpu.general >= bl.general && cpu.fixed >= bl.fixed; +} + +static_always_inline u8 is_bundle_supported (perfmon_bundle_t *b) { perfmon_cpu_supports_t *supports = b->cpu_supports; + if (!is_enough_counters (b)) + return 0; + if (!b->cpu_supports) return 1; @@ -372,13 +398,6 @@ perfmon_init (vlib_main_t *vm) clib_error_t *err; uword *p; - if (!is_bundle_supported (b)) - { - log_debug ("skipping bundle '%s' - not supported", b->name); - b = b->next; - continue; - } - if (hash_get_mem (pm->bundle_by_name, b->name) != 0) clib_panic ("duplicate bundle name '%s'", b->name); @@ -391,6 +410,13 @@ perfmon_init (vlib_main_t *vm) } b->src = (perfmon_source_t *) p[0]; + if (!is_bundle_supported (b)) + { + log_debug ("skipping bundle '%s' - not supported", b->name); + b = b->next; + continue; + } + if (b->init_fn && ((err = (b->init_fn) (vm, b)))) { log_warn ("skipping bundle '%s' - %U", b->name, format_clib_error, |