X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fperfmon%2Fperfmon.h;h=fa15ef63aca85794581905f5e3a9be88cb7a2ed5;hb=489d89c1cb7c57edca215c4eb2e6d1af3b75b147;hp=f24a23bd9748d6b3b3022c9a862fd767e85ad330;hpb=7e3862927ec0fd92a1237a9b4286aaf410f34166;p=vpp.git diff --git a/src/plugins/perfmon/perfmon.h b/src/plugins/perfmon/perfmon.h index f24a23bd974..fa15ef63aca 100644 --- a/src/plugins/perfmon/perfmon.h +++ b/src/plugins/perfmon/perfmon.h @@ -20,9 +20,18 @@ #include #include #include +#include #include -#define PERF_MAX_EVENTS 7 /* 3 fixed and 4 programmable */ +#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 { @@ -30,8 +39,24 @@ typedef enum PERFMON_BUNDLE_TYPE_NODE, PERFMON_BUNDLE_TYPE_THREAD, PERFMON_BUNDLE_TYPE_SYSTEM, + PERFMON_BUNDLE_TYPE_MAX, + PERFMON_BUNDLE_TYPE_NODE_OR_THREAD, } perfmon_bundle_type_t; +#define foreach_perfmon_bundle_type \ + _ (PERFMON_BUNDLE_TYPE_UNKNOWN, "not supported") \ + _ (PERFMON_BUNDLE_TYPE_NODE, "node") \ + _ (PERFMON_BUNDLE_TYPE_THREAD, "thread") \ + _ (PERFMON_BUNDLE_TYPE_SYSTEM, "system") + +typedef enum +{ +#define _(e, str) e##_FLAG = 1 << e, + foreach_perfmon_bundle_type +#undef _ + +} perfmon_bundle_type_flag_t; + typedef struct { u32 type_from_instance : 1; @@ -61,10 +86,12 @@ typedef struct } perfmon_instance_type_t; struct perfmon_source; -vlib_node_function_t perfmon_dispatch_wrapper; +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 perfmon_event_type_t (perfmon_source_get_event_type) (u32 event); + typedef struct perfmon_source { char *name; @@ -74,26 +101,46 @@ typedef struct perfmon_source u32 n_events; perfmon_instance_type_t *instances_by_type; format_function_t *format_config; + perfmon_source_get_event_type *get_event_type; perfmon_source_init_fn_t *init_fn; } perfmon_source_t; struct perfmon_bundle; + typedef clib_error_t *(perfmon_bundle_init_fn_t) (vlib_main_t *vm, struct perfmon_bundle *); + +typedef struct +{ + clib_cpu_supports_func_t cpu_supports; + perfmon_bundle_type_t bundle_type; +} perfmon_cpu_supports_t; + typedef struct perfmon_bundle { char *name; char *description; char *source; char *footer; - perfmon_bundle_type_t type; + + union + { + perfmon_bundle_type_flag_t type_flags; + perfmon_bundle_type_t type; + }; + perfmon_bundle_type_t active_type; + u32 events[PERF_MAX_EVENTS]; u32 n_events; + u16 preserve_samples; + + perfmon_cpu_supports_t *cpu_supports; + u32 n_cpu_supports; + perfmon_bundle_init_fn_t *init_fn; char **column_headers; - char **raw_column_headers; format_function_t *format_fn; /* do not set manually */ @@ -114,7 +161,14 @@ typedef struct CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); u64 n_calls; u64 n_packets; - u64 value[PERF_MAX_EVENTS]; + union + { + struct + { + u64 value[PERF_MAX_EVENTS]; + } t[2]; + u64 value[PERF_MAX_EVENTS * 2]; + }; } perfmon_node_stats_t; typedef struct @@ -122,6 +176,9 @@ typedef struct u8 n_events; u16 n_nodes; perfmon_node_stats_t *node_stats; + perfmon_bundle_t *bundle; + u32 indexes[PERF_MAX_EVENTS]; + u16 preserve_samples; struct perf_event_mmap_page *mmap_pages[PERF_MAX_EVENTS]; } perfmon_thread_runtime_t; @@ -143,6 +200,41 @@ typedef struct extern perfmon_main_t perfmon_main; +#define PERFMON_BUNDLE_TYPE_TO_FLAGS(type) \ + ({ \ + uword rtype = 0; \ + if (type == PERFMON_BUNDLE_TYPE_NODE_OR_THREAD) \ + rtype = \ + 1 << PERFMON_BUNDLE_TYPE_THREAD | 1 << PERFMON_BUNDLE_TYPE_NODE; \ + else \ + rtype = 1 << type; \ + rtype; \ + }) + +always_inline uword +perfmon_cpu_update_bundle_type (perfmon_bundle_t *b) +{ + perfmon_cpu_supports_t *supports = b->cpu_supports; + uword type = 0; + + /* either supports or b->type should be set, but not both */ + ASSERT (!!supports ^ !!b->type); + + /* if nothing specific for this bundle, go with the defaults */ + if (!supports) + type = PERFMON_BUNDLE_TYPE_TO_FLAGS (b->type); + else + { + /* more than one type may be supported by a given bundle */ + for (int i = 0; i < b->n_cpu_supports; ++i) + if (supports[i].cpu_supports ()) + type |= PERFMON_BUNDLE_TYPE_TO_FLAGS (supports[i].bundle_type); + } + + return type; +} +#undef PERFMON_BUNDLE_TYPE_TO_FLAGS + #define PERFMON_REGISTER_SOURCE(x) \ perfmon_source_t __perfmon_source_##x; \ static void __clib_constructor __perfmon_source_registration_##x (void) \ @@ -159,6 +251,8 @@ extern perfmon_main_t perfmon_main; { \ perfmon_main_t *pm = &perfmon_main; \ __perfmon_bundle_##x.next = pm->bundles; \ + __perfmon_bundle_##x.type_flags = \ + perfmon_cpu_update_bundle_type (&__perfmon_bundle_##x); \ pm->bundles = &__perfmon_bundle_##x; \ } \ perfmon_bundle_t __perfmon_bundle_##x