1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
5 #include <vppinfra/format.h>
6 #include <vppinfra/test/test.h>
7 #include <vppinfra/error.h>
12 test_march_supported (clib_march_variant_type_t type)
15 if (CLIB_MARCH_VARIANT_TYPE_##s == type) \
16 return clib_cpu_march_priority_##s ();
23 test_funct (test_main_t *tm)
25 for (int i = 0; i < CLIB_MARCH_TYPE_N_VARIANTS; i++)
27 test_registration_t *r = tm->registrations[i];
29 if (r == 0 || test_march_supported (i) < 0)
32 fformat (stdout, "\nMultiarch Variant: %U\n", format_march_variant, i);
34 "-------------------------------------------------------\n");
38 if (tm->filter && strstr (r->name, (char *) tm->filter) == 0)
41 fformat (stdout, "%-50s %s\n", r->name, err ? "FAIL" : "PASS");
44 clib_error_report (err);
45 fformat (stdout, "\n");
52 fformat (stdout, "\n");
58 format_test_perf_bundle_core_power (u8 *s, va_list *args)
60 test_perf_event_bundle_t __clib_unused *b =
61 va_arg (*args, test_perf_event_bundle_t *);
62 test_perf_t __clib_unused *tp = va_arg (*args, test_perf_t *);
63 u64 *data = va_arg (*args, u64 *);
66 s = format (s, "%7.1f %%", (f64) 100 * data[1] / data[0]);
68 s = format (s, "%9s", "Level 0");
71 s = format (s, "%8.1f %%", (f64) 100 * data[2] / data[0]);
73 s = format (s, "%9s", "Level 1");
76 s = format (s, "%7.1f %%", (f64) 100 * data[3] / data[0]);
78 s = format (s, "%9s", "Level 2");
84 #define PERF_INTEL_CODE(event, umask) ((event) | (umask) << 8)
89 "Core cycles where the core was running under specific turbo schedule.",
90 .type = PERF_TYPE_RAW,
91 .config[0] = PERF_INTEL_CODE (0x3c, 0x00),
92 .config[1] = PERF_INTEL_CODE (0x28, 0x07),
93 .config[2] = PERF_INTEL_CODE (0x28, 0x18),
94 .config[3] = PERF_INTEL_CODE (0x28, 0x20),
95 .config[4] = PERF_INTEL_CODE (0x28, 0x40),
97 .format_fn = format_test_perf_bundle_core_power,
105 test_perf (test_main_t *tm)
107 clib_error_t *err = 0;
108 clib_perfmon_ctx_t _ctx, *ctx = &_ctx;
110 if ((err = clib_perfmon_init_by_bundle_name (
111 ctx, "%s", tm->bundle ? (char *) tm->bundle : "default")))
114 fformat (stdout, "Warming up...\n");
115 clib_perfmon_warmup (ctx);
117 for (int i = 0; i < CLIB_MARCH_TYPE_N_VARIANTS; i++)
119 test_registration_t *r = tm->registrations[i];
121 if (r == 0 || test_march_supported (i) < 0)
124 fformat (stdout, "\nMultiarch Variant: %U\n", format_march_variant, i);
126 "-------------------------------------------------------\n");
131 test_perf_t *pt = r->perf_tests;
132 if (tm->filter && strstr (r->name, (char *) tm->filter) == 0)
135 clib_perfmon_capture_group (ctx, "%s", r->name);
138 for (int i = 0; i < tm->repeat; i++)
140 pt->fd = ctx->group_fd;
141 clib_perfmon_reset (ctx);
143 clib_perfmon_capture (ctx, pt->n_ops, "%0s", pt->name);
151 fformat (stdout, "%U\n", format_perfmon_bundle, ctx);
152 clib_perfmon_clear (ctx);
155 clib_perfmon_free (ctx);
161 main (int argc, char *argv[])
163 test_main_t *tm = &test_main;
164 unformat_input_t _i = {}, *i = &_i;
165 clib_mem_init (0, 64ULL << 20);
172 unformat_init_command_line (i, argv);
174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
176 if (unformat (i, "perf"))
178 else if (unformat (i, "filter %s", &tm->filter))
180 else if (unformat (i, "bundle %s", &tm->bundle))
182 else if (unformat (i, "repeat %d", &tm->repeat))
186 clib_warning ("unknown input '%U'", format_unformat_error, i);
192 err = test_perf (tm);
194 err = test_funct (tm);
198 clib_error_report (err);
199 fformat (stderr, "\n");
206 test_mem_alloc (uword size)
209 size = round_pow2 (size, CLIB_CACHE_LINE_BYTES);
210 rv = clib_mem_alloc_aligned (size, CLIB_CACHE_LINE_BYTES);
211 clib_memset_u8 (rv, 0, size);
216 test_mem_alloc_and_fill_inc_u8 (uword size, u8 start, u8 mask)
219 mask = mask ? mask : 0xff;
220 size = round_pow2 (size, CLIB_CACHE_LINE_BYTES);
221 rv = clib_mem_alloc_aligned (size, CLIB_CACHE_LINE_BYTES);
222 for (uword i = 0; i < size; i++)
223 rv[i] = ((u8) i + start) & mask;
228 test_mem_alloc_and_splat (uword elt_size, uword n_elts, void *elt)
231 uword data_size = elt_size * n_elts;
232 uword alloc_size = round_pow2 (data_size, CLIB_CACHE_LINE_BYTES);
233 e = rv = clib_mem_alloc_aligned (alloc_size, CLIB_CACHE_LINE_BYTES);
234 while (e - rv < data_size)
236 clib_memcpy_fast (e, elt, elt_size);
240 if (data_size < alloc_size)
241 clib_memset_u8 (e, 0, alloc_size - data_size);
246 test_mem_free (void *p)