perfmon: fix init of bundles with pseudo events
Previously Linux pseudo events were being counted as multiple fixed
events, such that a bundle with pseudo events could exceed the number of
available fixed counters. Reworked to ignore pseudo events in the
accounting for the moment.
Type: fix
Fixes: 0024e53ad
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
Change-Id: Ic938f8266fd04d7731afbd02e261c61ef22a8522
This commit is contained in:

committed by
Damjan Marion

parent
0a0e711cce
commit
7e8aeb876b
@ -77,13 +77,22 @@ intel_core_init (vlib_main_t *vm, perfmon_source_t *src)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8
|
||||
intel_core_is_fixed (u32 event)
|
||||
perfmon_event_type_t
|
||||
intel_core_get_event_type (u32 event)
|
||||
{
|
||||
u64 config = events[event].config;
|
||||
u8 eventcode = (config & 0xFF);
|
||||
u8 umask = ((config >> 8) & 0xFF);
|
||||
|
||||
return !eventcode ? 1 : 0;
|
||||
if (!eventcode) /* is fixed or pseudo */
|
||||
{
|
||||
if (umask >= 0x80) /* is pseudo */
|
||||
return PERFMON_EVENT_TYPE_PSEUDO;
|
||||
else /* is fixed */
|
||||
return PERFMON_EVENT_TYPE_FIXED;
|
||||
}
|
||||
else
|
||||
return PERFMON_EVENT_TYPE_GENERAL;
|
||||
}
|
||||
|
||||
PERFMON_REGISTER_SOURCE (intel_core) = {
|
||||
@ -92,6 +101,6 @@ PERFMON_REGISTER_SOURCE (intel_core) = {
|
||||
.events = events,
|
||||
.n_events = ARRAY_LEN (events),
|
||||
.init_fn = intel_core_init,
|
||||
.is_fixed = intel_core_is_fixed,
|
||||
.get_event_type = intel_core_get_event_type,
|
||||
.format_config = format_intel_core_config,
|
||||
};
|
||||
|
@ -327,24 +327,30 @@ 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 };
|
||||
u8 bl[PERFMON_EVENT_TYPE_MAX];
|
||||
u8 cpu[PERFMON_EVENT_TYPE_MAX];
|
||||
|
||||
clib_memset (&bl, 0, sizeof (bl));
|
||||
clib_memset (&cpu, 0, sizeof (cpu));
|
||||
|
||||
/* how many does this uarch support */
|
||||
if (!clib_get_pmu_counter_count (&cpu.fixed, &cpu.general))
|
||||
if (!clib_get_pmu_counter_count (&cpu[PERFMON_EVENT_TYPE_FIXED],
|
||||
&cpu[PERFMON_EVENT_TYPE_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++;
|
||||
{
|
||||
/* if source allows us to identify events, otherwise assume general */
|
||||
if (b->src->get_event_type)
|
||||
bl[b->src->get_event_type (b->events[i])]++;
|
||||
else
|
||||
bl[PERFMON_EVENT_TYPE_GENERAL]++;
|
||||
}
|
||||
|
||||
return cpu.general >= bl.general && cpu.fixed >= bl.fixed;
|
||||
/* consciously ignoring pseudo events here */
|
||||
return cpu[PERFMON_EVENT_TYPE_GENERAL] >= bl[PERFMON_EVENT_TYPE_GENERAL] &&
|
||||
cpu[PERFMON_EVENT_TYPE_FIXED] >= bl[PERFMON_EVENT_TYPE_FIXED];
|
||||
}
|
||||
|
||||
static_always_inline u8
|
||||
|
@ -25,6 +25,14 @@
|
||||
|
||||
#define PERF_MAX_EVENTS 12 /* 4 fixed and 8 programable on ICX */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PERFMON_EVENT_TYPE_GENERAL,
|
||||
PERFMON_EVENT_TYPE_FIXED,
|
||||
PERFMON_EVENT_TYPE_PSEUDO,
|
||||
PERFMON_EVENT_TYPE_MAX,
|
||||
} perfmon_event_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PERFMON_BUNDLE_TYPE_UNKNOWN,
|
||||
@ -82,7 +90,7 @@ 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 perfmon_event_type_t (perfmon_source_get_event_type) (u32 event);
|
||||
|
||||
typedef struct perfmon_source
|
||||
{
|
||||
@ -93,7 +101,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_get_event_type *get_event_type;
|
||||
perfmon_source_init_fn_t *init_fn;
|
||||
} perfmon_source_t;
|
||||
|
||||
|
Reference in New Issue
Block a user