perfmon: prune bundles by available pmu counters
Prune perfmon bundles that exceed the number of available pmu counters. Type: improvement Signed-off-by: Ray Kinsella <mdr@ashroe.eu> Change-Id: I70fec26bb8ca915f4b980963e06c2e43dfde5a23
This commit is contained in:
committed by
Damjan Marion
parent
ae0e3e748f
commit
0024e53ad0
@@ -77,11 +77,21 @@ intel_core_init (vlib_main_t *vm, perfmon_source_t *src)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8
|
||||
intel_core_is_fixed (u32 event)
|
||||
{
|
||||
u64 config = events[event].config;
|
||||
u8 eventcode = (config & 0xFF);
|
||||
|
||||
return !eventcode ? 1 : 0;
|
||||
}
|
||||
|
||||
PERFMON_REGISTER_SOURCE (intel_core) = {
|
||||
.name = "intel-core",
|
||||
.description = "intel arch core events",
|
||||
.events = events,
|
||||
.n_events = ARRAY_LEN (events),
|
||||
.init_fn = intel_core_init,
|
||||
.is_fixed = intel_core_is_fixed,
|
||||
.format_config = format_intel_core_config,
|
||||
};
|
||||
|
||||
@@ -324,11 +324,37 @@ perfmon_stop (vlib_main_t *vm)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@@ -82,6 +82,8 @@ extern vlib_node_function_t *perfmon_dispatch_wrappers[PERF_MAX_EVENTS + 1];
|
||||
|
||||
typedef clib_error_t *(perfmon_source_init_fn_t) (vlib_main_t *vm,
|
||||
struct perfmon_source *);
|
||||
typedef u8 (perfmon_source_is_fixed) (u32 event);
|
||||
|
||||
typedef struct perfmon_source
|
||||
{
|
||||
char *name;
|
||||
@@ -91,6 +93,7 @@ typedef struct perfmon_source
|
||||
u32 n_events;
|
||||
perfmon_instance_type_t *instances_by_type;
|
||||
format_function_t *format_config;
|
||||
perfmon_source_is_fixed *is_fixed;
|
||||
perfmon_source_init_fn_t *init_fn;
|
||||
} perfmon_source_t;
|
||||
|
||||
|
||||
@@ -266,6 +266,24 @@ clib_cpu_march_priority_hsw ()
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define X86_CPU_ARCH_PERF_FUNC 0xA
|
||||
|
||||
static inline int
|
||||
clib_get_pmu_counter_count (u8 *fixed, u8 *general)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
u32 __clib_unused eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
clib_get_cpuid (X86_CPU_ARCH_PERF_FUNC, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
*general = (eax & 0xFF00) >> 8;
|
||||
*fixed = (edx & 0xF);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline u32
|
||||
clib_cpu_implementer ()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user