summaryrefslogtreecommitdiffstats
path: root/src/plugins/perfmon/perfmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/perfmon/perfmon.c')
-rw-r--r--src/plugins/perfmon/perfmon.c40
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,