blob: 55c2ae7a11fd0a128ae09d435c87de418de4c9a0 [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 Marionc3542e12023-03-15 11:42:06 +00006#include <vppinfra/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");
Damjan Marionc7d3a5b2023-03-16 16:55:38 +000042 for (int i = 0; i < vec_len (tm->allocated_mem); i++)
43 clib_mem_free (tm->allocated_mem[i]);
44 vec_free (tm->allocated_mem);
Damjan Marione3e35552021-05-06 17:34:49 +020045 if (err)
46 {
47 clib_error_report (err);
48 fformat (stdout, "\n");
49 }
Damjan Marion68843d12021-12-06 13:21:33 +010050 next:
Damjan Marione3e35552021-05-06 17:34:49 +020051 r = r->next;
52 }
53 }
54
55 fformat (stdout, "\n");
56 return 0;
57}
Damjan Marion3323e202021-12-02 11:28:57 +010058
Damjan Mariond5045e62022-04-06 21:16:37 +020059#if 0
Damjan Marionb97bec02021-12-12 21:43:56 +000060static u8 *
61format_test_perf_bundle_core_power (u8 *s, va_list *args)
62{
63 test_perf_event_bundle_t __clib_unused *b =
64 va_arg (*args, test_perf_event_bundle_t *);
65 test_perf_t __clib_unused *tp = va_arg (*args, test_perf_t *);
66 u64 *data = va_arg (*args, u64 *);
67
68 if (data)
69 s = format (s, "%7.1f %%", (f64) 100 * data[1] / data[0]);
70 else
71 s = format (s, "%9s", "Level 0");
72
73 if (data)
74 s = format (s, "%8.1f %%", (f64) 100 * data[2] / data[0]);
75 else
76 s = format (s, "%9s", "Level 1");
77
78 if (data)
79 s = format (s, "%7.1f %%", (f64) 100 * data[3] / data[0]);
80 else
81 s = format (s, "%9s", "Level 2");
82
83 return s;
84}
85
Damjan Marionb97bec02021-12-12 21:43:56 +000086#ifdef __x86_64__
87#define PERF_INTEL_CODE(event, umask) ((event) | (umask) << 8)
88 ,
89 {
90 .name = "core-power",
91 .desc =
92 "Core cycles where the core was running under specific turbo schedule.",
93 .type = PERF_TYPE_RAW,
94 .config[0] = PERF_INTEL_CODE (0x3c, 0x00),
95 .config[1] = PERF_INTEL_CODE (0x28, 0x07),
96 .config[2] = PERF_INTEL_CODE (0x28, 0x18),
97 .config[3] = PERF_INTEL_CODE (0x28, 0x20),
98 .config[4] = PERF_INTEL_CODE (0x28, 0x40),
99 .n_events = 5,
100 .format_fn = format_test_perf_bundle_core_power,
101 }
102#endif
103};
Damjan Mariond5045e62022-04-06 21:16:37 +0200104#endif
Damjan Marion3323e202021-12-02 11:28:57 +0100105
106#ifdef __linux__
107clib_error_t *
108test_perf (test_main_t *tm)
109{
110 clib_error_t *err = 0;
Damjan Mariond5045e62022-04-06 21:16:37 +0200111 clib_perfmon_ctx_t _ctx, *ctx = &_ctx;
Damjan Marion3323e202021-12-02 11:28:57 +0100112
Damjan Mariond5045e62022-04-06 21:16:37 +0200113 if ((err = clib_perfmon_init_by_bundle_name (
114 ctx, "%s", tm->bundle ? (char *) tm->bundle : "default")))
115 return err;
Damjan Marion3323e202021-12-02 11:28:57 +0100116
Damjan Marionf622bf42021-12-14 10:40:48 +0100117 fformat (stdout, "Warming up...\n");
Damjan Mariond5045e62022-04-06 21:16:37 +0200118 clib_perfmon_warmup (ctx);
Damjan Marion3323e202021-12-02 11:28:57 +0100119
120 for (int i = 0; i < CLIB_MARCH_TYPE_N_VARIANTS; i++)
121 {
122 test_registration_t *r = tm->registrations[i];
123
124 if (r == 0 || test_march_supported (i) < 0)
125 continue;
126
127 fformat (stdout, "\nMultiarch Variant: %U\n", format_march_variant, i);
128 fformat (stdout,
129 "-------------------------------------------------------\n");
130 while (r)
131 {
132 if (r->perf_tests)
133 {
134 test_perf_t *pt = r->perf_tests;
Damjan Marion68843d12021-12-06 13:21:33 +0100135 if (tm->filter && strstr (r->name, (char *) tm->filter) == 0)
136 goto next;
Damjan Mariond5045e62022-04-06 21:16:37 +0200137
138 clib_perfmon_capture_group (ctx, "%s", r->name);
Damjan Marion3323e202021-12-02 11:28:57 +0100139 do
140 {
Damjan Marion3323e202021-12-02 11:28:57 +0100141 for (int i = 0; i < tm->repeat; i++)
142 {
Damjan Mariond5045e62022-04-06 21:16:37 +0200143 pt->fd = ctx->group_fd;
144 clib_perfmon_reset (ctx);
145 pt->fn (pt);
146 clib_perfmon_capture (ctx, pt->n_ops, "%0s", pt->name);
Damjan Marionc7d3a5b2023-03-16 16:55:38 +0000147 for (int i = 0; i < vec_len (tm->allocated_mem); i++)
148 clib_mem_free (tm->allocated_mem[i]);
149 vec_free (tm->allocated_mem);
Damjan Marion3323e202021-12-02 11:28:57 +0100150 }
151 }
152 while ((++pt)->fn);
153 }
Damjan Marion68843d12021-12-06 13:21:33 +0100154 next:
Damjan Marion3323e202021-12-02 11:28:57 +0100155 r = r->next;
156 }
Damjan Mariond5045e62022-04-06 21:16:37 +0200157 fformat (stdout, "%U\n", format_perfmon_bundle, ctx);
158 clib_perfmon_clear (ctx);
Damjan Marion3323e202021-12-02 11:28:57 +0100159 }
160
Damjan Mariond5045e62022-04-06 21:16:37 +0200161 clib_perfmon_free (ctx);
Damjan Marion3323e202021-12-02 11:28:57 +0100162 return err;
163}
Tom Jones7c041542024-01-26 15:20:02 +0000164#elif __FreeBSD__
165clib_error_t *
166test_perf (test_main_t *tm)
167{
168 return NULL;
169}
Damjan Marion3323e202021-12-02 11:28:57 +0100170#endif
171
172int
173main (int argc, char *argv[])
174{
175 test_main_t *tm = &test_main;
176 unformat_input_t _i = {}, *i = &_i;
177 clib_mem_init (0, 64ULL << 20);
178 clib_error_t *err;
179 int perf = 0;
180
181 /* defaults */
182 tm->repeat = 3;
183
184 unformat_init_command_line (i, argv);
185
186 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
187 {
188 if (unformat (i, "perf"))
189 perf = 1;
Damjan Marion68843d12021-12-06 13:21:33 +0100190 else if (unformat (i, "filter %s", &tm->filter))
191 ;
Damjan Marionb97bec02021-12-12 21:43:56 +0000192 else if (unformat (i, "bundle %s", &tm->bundle))
193 ;
Damjan Marion3323e202021-12-02 11:28:57 +0100194 else if (unformat (i, "repeat %d", &tm->repeat))
195 ;
196 else
197 {
198 clib_warning ("unknown input '%U'", format_unformat_error, i);
199 exit (1);
200 }
201 }
202
203 if (perf)
204 err = test_perf (tm);
205 else
206 err = test_funct (tm);
207
208 if (err)
209 {
210 clib_error_report (err);
211 fformat (stderr, "\n");
212 return 1;
213 }
214 return 0;
215}
216
217void *
218test_mem_alloc (uword size)
219{
220 void *rv;
221 size = round_pow2 (size, CLIB_CACHE_LINE_BYTES);
222 rv = clib_mem_alloc_aligned (size, CLIB_CACHE_LINE_BYTES);
223 clib_memset_u8 (rv, 0, size);
Damjan Marionc7d3a5b2023-03-16 16:55:38 +0000224 vec_add1 (test_main.allocated_mem, rv);
Damjan Marion3323e202021-12-02 11:28:57 +0100225 return rv;
226}
227
228void *
229test_mem_alloc_and_fill_inc_u8 (uword size, u8 start, u8 mask)
230{
231 u8 *rv;
232 mask = mask ? mask : 0xff;
233 size = round_pow2 (size, CLIB_CACHE_LINE_BYTES);
234 rv = clib_mem_alloc_aligned (size, CLIB_CACHE_LINE_BYTES);
235 for (uword i = 0; i < size; i++)
236 rv[i] = ((u8) i + start) & mask;
Damjan Marionc7d3a5b2023-03-16 16:55:38 +0000237 vec_add1 (test_main.allocated_mem, rv);
Damjan Marion3323e202021-12-02 11:28:57 +0100238 return rv;
239}
240
241void *
242test_mem_alloc_and_splat (uword elt_size, uword n_elts, void *elt)
243{
244 u8 *rv, *e;
245 uword data_size = elt_size * n_elts;
246 uword alloc_size = round_pow2 (data_size, CLIB_CACHE_LINE_BYTES);
247 e = rv = clib_mem_alloc_aligned (alloc_size, CLIB_CACHE_LINE_BYTES);
248 while (e - rv < data_size)
249 {
250 clib_memcpy_fast (e, elt, elt_size);
251 e += elt_size;
252 }
253
254 if (data_size < alloc_size)
255 clib_memset_u8 (e, 0, alloc_size - data_size);
Damjan Marionc7d3a5b2023-03-16 16:55:38 +0000256 vec_add1 (test_main.allocated_mem, rv);
Damjan Marion3323e202021-12-02 11:28:57 +0100257 return rv;
258}
259