summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vppinfra/vector/test/test.c88
-rw-r--r--src/vppinfra/vector/test/test.h1
2 files changed, 79 insertions, 10 deletions
diff --git a/src/vppinfra/vector/test/test.c b/src/vppinfra/vector/test/test.c
index 144604e5fcd..7cbd33f5a73 100644
--- a/src/vppinfra/vector/test/test.c
+++ b/src/vppinfra/vector/test/test.c
@@ -56,7 +56,10 @@ test_funct (test_main_t *tm)
#define TEST_PERF_MAX_EVENTS 7
typedef struct
{
+ char *name;
+ char *desc;
u64 config[TEST_PERF_MAX_EVENTS];
+ u32 type;
u8 n_events;
format_function_t *format_fn;
} test_perf_event_bundle_t;
@@ -96,26 +99,73 @@ format_test_perf_bundle_default (u8 *s, va_list *args)
return s;
}
-test_perf_event_bundle_t perf_bundles[] = { {
- .config[0] = PERF_COUNT_HW_CPU_CYCLES,
- .config[1] = PERF_COUNT_HW_INSTRUCTIONS,
- .config[2] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
- .config[3] = PERF_COUNT_HW_BRANCH_MISSES,
- .n_events = 4,
- .format_fn = format_test_perf_bundle_default,
-} };
+static u8 *
+format_test_perf_bundle_core_power (u8 *s, va_list *args)
+{
+ test_perf_event_bundle_t __clib_unused *b =
+ va_arg (*args, test_perf_event_bundle_t *);
+ test_perf_t __clib_unused *tp = va_arg (*args, test_perf_t *);
+ u64 *data = va_arg (*args, u64 *);
+
+ if (data)
+ s = format (s, "%7.1f %%", (f64) 100 * data[1] / data[0]);
+ else
+ s = format (s, "%9s", "Level 0");
+
+ if (data)
+ s = format (s, "%8.1f %%", (f64) 100 * data[2] / data[0]);
+ else
+ s = format (s, "%9s", "Level 1");
+
+ if (data)
+ s = format (s, "%7.1f %%", (f64) 100 * data[3] / data[0]);
+ else
+ s = format (s, "%9s", "Level 2");
+
+ return s;
+}
+
+test_perf_event_bundle_t perf_bundles[] = {
+ {
+ .name = "default",
+ .desc = "IPC, Clocks/Operatiom, Instr/Operation, Branch Total & Miss",
+ .type = PERF_TYPE_HARDWARE,
+ .config[0] = PERF_COUNT_HW_CPU_CYCLES,
+ .config[1] = PERF_COUNT_HW_INSTRUCTIONS,
+ .config[2] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
+ .config[3] = PERF_COUNT_HW_BRANCH_MISSES,
+ .n_events = 4,
+ .format_fn = format_test_perf_bundle_default,
+ }
+#ifdef __x86_64__
+#define PERF_INTEL_CODE(event, umask) ((event) | (umask) << 8)
+ ,
+ {
+ .name = "core-power",
+ .desc =
+ "Core cycles where the core was running under specific turbo schedule.",
+ .type = PERF_TYPE_RAW,
+ .config[0] = PERF_INTEL_CODE (0x3c, 0x00),
+ .config[1] = PERF_INTEL_CODE (0x28, 0x07),
+ .config[2] = PERF_INTEL_CODE (0x28, 0x18),
+ .config[3] = PERF_INTEL_CODE (0x28, 0x20),
+ .config[4] = PERF_INTEL_CODE (0x28, 0x40),
+ .n_events = 5,
+ .format_fn = format_test_perf_bundle_core_power,
+ }
+#endif
+};
#ifdef __linux__
clib_error_t *
test_perf (test_main_t *tm)
{
clib_error_t *err = 0;
- test_perf_event_bundle_t *b = perf_bundles;
+ test_perf_event_bundle_t *b = 0;
int group_fd = -1, fds[TEST_PERF_MAX_EVENTS];
u64 count[TEST_PERF_MAX_EVENTS + 3] = {};
struct perf_event_attr pe = {
.size = sizeof (struct perf_event_attr),
- .type = PERF_TYPE_HARDWARE,
.disabled = 1,
.exclude_kernel = 1,
.exclude_hv = 1,
@@ -128,9 +178,25 @@ test_perf (test_main_t *tm)
for (int i = 0; i < TEST_PERF_MAX_EVENTS; i++)
fds[i] = -1;
+ if (tm->bundle)
+ {
+ for (int i = 0; i < ARRAY_LEN (perf_bundles); i++)
+ if (strncmp ((char *) tm->bundle, perf_bundles[i].name,
+ vec_len (tm->bundle)) == 0)
+ {
+ b = perf_bundles + i;
+ break;
+ }
+ if (b == 0)
+ return clib_error_return (0, "Unknown bundle '%s'", tm->bundle);
+ }
+ else
+ b = perf_bundles;
+
for (int i = 0; i < b->n_events; i++)
{
pe.config = b->config[i];
+ pe.type = b->type;
int fd = syscall (__NR_perf_event_open, &pe, /* pid */ 0, /* cpu */ -1,
/* group_fd */ group_fd, /* flags */ 0);
if (fd < 0)
@@ -227,6 +293,8 @@ main (int argc, char *argv[])
perf = 1;
else if (unformat (i, "filter %s", &tm->filter))
;
+ else if (unformat (i, "bundle %s", &tm->bundle))
+ ;
else if (unformat (i, "repeat %d", &tm->repeat))
;
else
diff --git a/src/vppinfra/vector/test/test.h b/src/vppinfra/vector/test/test.h
index 16622877c45..b1478fc6fe6 100644
--- a/src/vppinfra/vector/test/test.h
+++ b/src/vppinfra/vector/test/test.h
@@ -54,6 +54,7 @@ typedef struct
test_registration_t *registrations[CLIB_MARCH_TYPE_N_VARIANTS];
u32 repeat;
u8 *filter;
+ u8 *bundle;
} test_main_t;
extern test_main_t test_main;