blob: dc5651c47cc32d68a728af0a978481fbfbdfbb30 [file] [log] [blame]
Damjan Marione3e35552021-05-06 17:34:49 +02001/* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2021 Cisco Systems, Inc.
3 */
4
5#include <vppinfra/format.h>
Damjan Mariond154a172021-07-13 21:12:41 +02006#include <vppinfra/vector/test/test.h>
Damjan Marion3323e202021-12-02 11:28:57 +01007#include <vppinfra/error.h>
Damjan Marione3e35552021-05-06 17:34:49 +02008
Damjan Marion3323e202021-12-02 11:28:57 +01009test_main_t test_main;
Damjan Marione3e35552021-05-06 17:34:49 +020010
11int
Mohsin Kazmi85010602021-07-15 14:20:57 +000012test_march_supported (clib_march_variant_type_t type)
13{
14#define _(s, n) \
15 if (CLIB_MARCH_VARIANT_TYPE_##s == type) \
16 return clib_cpu_march_priority_##s ();
17 foreach_march_variant
18#undef _
19 return 0;
20}
21
Damjan Marion3323e202021-12-02 11:28:57 +010022clib_error_t *
23test_funct (test_main_t *tm)
Damjan Marione3e35552021-05-06 17:34:49 +020024{
Damjan Marione3e35552021-05-06 17:34:49 +020025 for (int i = 0; i < CLIB_MARCH_TYPE_N_VARIANTS; i++)
26 {
Damjan Marion3323e202021-12-02 11:28:57 +010027 test_registration_t *r = tm->registrations[i];
Damjan Marione3e35552021-05-06 17:34:49 +020028
Mohsin Kazmi85010602021-07-15 14:20:57 +000029 if (r == 0 || test_march_supported (i) < 0)
Damjan Marione3e35552021-05-06 17:34:49 +020030 continue;
31
32 fformat (stdout, "\nMultiarch Variant: %U\n", format_march_variant, i);
33 fformat (stdout,
34 "-------------------------------------------------------\n");
35 while (r)
36 {
37 clib_error_t *err;
Damjan Marion68843d12021-12-06 13:21:33 +010038 if (tm->filter && strstr (r->name, (char *) tm->filter) == 0)
39 goto next;
Damjan Marione3e35552021-05-06 17:34:49 +020040 err = (r->fn) (0);
41 fformat (stdout, "%-50s %s\n", r->name, err ? "FAIL" : "PASS");
42 if (err)
43 {
44 clib_error_report (err);
45 fformat (stdout, "\n");
46 }
Damjan Marion68843d12021-12-06 13:21:33 +010047 next:
Damjan Marione3e35552021-05-06 17:34:49 +020048 r = r->next;
49 }
50 }
51
52 fformat (stdout, "\n");
53 return 0;
54}
Damjan Marion3323e202021-12-02 11:28:57 +010055
Damjan Mariond5045e62022-04-06 21:16:37 +020056#if 0
Damjan Marionb97bec02021-12-12 21:43:56 +000057static u8 *
58format_test_perf_bundle_core_power (u8 *s, va_list *args)
59{
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 *);
64
65 if (data)
66 s = format (s, "%7.1f %%", (f64) 100 * data[1] / data[0]);
67 else
68 s = format (s, "%9s", "Level 0");
69
70 if (data)
71 s = format (s, "%8.1f %%", (f64) 100 * data[2] / data[0]);
72 else
73 s = format (s, "%9s", "Level 1");
74
75 if (data)
76 s = format (s, "%7.1f %%", (f64) 100 * data[3] / data[0]);
77 else
78 s = format (s, "%9s", "Level 2");
79
80 return s;
81}
82
Damjan Marionb97bec02021-12-12 21:43:56 +000083#ifdef __x86_64__
84#define PERF_INTEL_CODE(event, umask) ((event) | (umask) << 8)
85 ,
86 {
87 .name = "core-power",
88 .desc =
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),
96 .n_events = 5,
97 .format_fn = format_test_perf_bundle_core_power,
98 }
99#endif
100};
Damjan Mariond5045e62022-04-06 21:16:37 +0200101#endif
Damjan Marion3323e202021-12-02 11:28:57 +0100102
103#ifdef __linux__
104clib_error_t *
105test_perf (test_main_t *tm)
106{
107 clib_error_t *err = 0;
Damjan Mariond5045e62022-04-06 21:16:37 +0200108 clib_perfmon_ctx_t _ctx, *ctx = &_ctx;
Damjan Marion3323e202021-12-02 11:28:57 +0100109
Damjan Mariond5045e62022-04-06 21:16:37 +0200110 if ((err = clib_perfmon_init_by_bundle_name (
111 ctx, "%s", tm->bundle ? (char *) tm->bundle : "default")))
112 return err;
Damjan Marion3323e202021-12-02 11:28:57 +0100113
Damjan Marionf622bf42021-12-14 10:40:48 +0100114 fformat (stdout, "Warming up...\n");
Damjan Mariond5045e62022-04-06 21:16:37 +0200115 clib_perfmon_warmup (ctx);
Damjan Marion3323e202021-12-02 11:28:57 +0100116
117 for (int i = 0; i < CLIB_MARCH_TYPE_N_VARIANTS; i++)
118 {
119 test_registration_t *r = tm->registrations[i];
120
121 if (r == 0 || test_march_supported (i) < 0)
122 continue;
123
124 fformat (stdout, "\nMultiarch Variant: %U\n", format_march_variant, i);
125 fformat (stdout,
126 "-------------------------------------------------------\n");
127 while (r)
128 {
129 if (r->perf_tests)
130 {
131 test_perf_t *pt = r->perf_tests;
Damjan Marion68843d12021-12-06 13:21:33 +0100132 if (tm->filter && strstr (r->name, (char *) tm->filter) == 0)
133 goto next;
Damjan Mariond5045e62022-04-06 21:16:37 +0200134
135 clib_perfmon_capture_group (ctx, "%s", r->name);
Damjan Marion3323e202021-12-02 11:28:57 +0100136 do
137 {
Damjan Marion3323e202021-12-02 11:28:57 +0100138 for (int i = 0; i < tm->repeat; i++)
139 {
Damjan Mariond5045e62022-04-06 21:16:37 +0200140 pt->fd = ctx->group_fd;
141 clib_perfmon_reset (ctx);
142 pt->fn (pt);
143 clib_perfmon_capture (ctx, pt->n_ops, "%0s", pt->name);
Damjan Marion3323e202021-12-02 11:28:57 +0100144 }
145 }
146 while ((++pt)->fn);
147 }
Damjan Marion68843d12021-12-06 13:21:33 +0100148 next:
Damjan Marion3323e202021-12-02 11:28:57 +0100149 r = r->next;
150 }
Damjan Mariond5045e62022-04-06 21:16:37 +0200151 fformat (stdout, "%U\n", format_perfmon_bundle, ctx);
152 clib_perfmon_clear (ctx);
Damjan Marion3323e202021-12-02 11:28:57 +0100153 }
154
Damjan Mariond5045e62022-04-06 21:16:37 +0200155 clib_perfmon_free (ctx);
Damjan Marion3323e202021-12-02 11:28:57 +0100156 return err;
157}
158#endif
159
160int
161main (int argc, char *argv[])
162{
163 test_main_t *tm = &test_main;
164 unformat_input_t _i = {}, *i = &_i;
165 clib_mem_init (0, 64ULL << 20);
166 clib_error_t *err;
167 int perf = 0;
168
169 /* defaults */
170 tm->repeat = 3;
171
172 unformat_init_command_line (i, argv);
173
174 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
175 {
176 if (unformat (i, "perf"))
177 perf = 1;
Damjan Marion68843d12021-12-06 13:21:33 +0100178 else if (unformat (i, "filter %s", &tm->filter))
179 ;
Damjan Marionb97bec02021-12-12 21:43:56 +0000180 else if (unformat (i, "bundle %s", &tm->bundle))
181 ;
Damjan Marion3323e202021-12-02 11:28:57 +0100182 else if (unformat (i, "repeat %d", &tm->repeat))
183 ;
184 else
185 {
186 clib_warning ("unknown input '%U'", format_unformat_error, i);
187 exit (1);
188 }
189 }
190
191 if (perf)
192 err = test_perf (tm);
193 else
194 err = test_funct (tm);
195
196 if (err)
197 {
198 clib_error_report (err);
199 fformat (stderr, "\n");
200 return 1;
201 }
202 return 0;
203}
204
205void *
206test_mem_alloc (uword size)
207{
208 void *rv;
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);
212 return rv;
213}
214
215void *
216test_mem_alloc_and_fill_inc_u8 (uword size, u8 start, u8 mask)
217{
218 u8 *rv;
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;
224 return rv;
225}
226
227void *
228test_mem_alloc_and_splat (uword elt_size, uword n_elts, void *elt)
229{
230 u8 *rv, *e;
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)
235 {
236 clib_memcpy_fast (e, elt, elt_size);
237 e += elt_size;
238 }
239
240 if (data_size < alloc_size)
241 clib_memset_u8 (e, 0, alloc_size - data_size);
242 return rv;
243}
244
245void
246test_mem_free (void *p)
247{
248 clib_mem_free (p);
249}