1
1
// SPDX-License-Identifier: GPL-2.0
2
2
#include <stdarg.h>
3
3
#include <stdio.h>
4
+ #include <string.h>
4
5
#include <linux/perf_event.h>
6
+ #include <linux/kernel.h>
5
7
#include <perf/cpumap.h>
6
8
#include <perf/threadmap.h>
7
9
#include <perf/evsel.h>
10
+ #include <internal/evsel.h>
8
11
#include <internal/tests.h>
9
12
#include "tests.h"
10
13
@@ -189,6 +192,163 @@ static int test_stat_user_read(int event)
189
192
return 0 ;
190
193
}
191
194
195
+ static int test_stat_read_format_single (struct perf_event_attr * attr , struct perf_thread_map * threads )
196
+ {
197
+ struct perf_evsel * evsel ;
198
+ struct perf_counts_values counts ;
199
+ volatile int count = 0x100000 ;
200
+ int err ;
201
+
202
+ evsel = perf_evsel__new (attr );
203
+ __T ("failed to create evsel" , evsel );
204
+
205
+ /* skip old kernels that don't support the format */
206
+ err = perf_evsel__open (evsel , NULL , threads );
207
+ if (err < 0 )
208
+ return 0 ;
209
+
210
+ while (count -- ) ;
211
+
212
+ memset (& counts , -1 , sizeof (counts ));
213
+ perf_evsel__read (evsel , 0 , 0 , & counts );
214
+
215
+ __T ("failed to read value" , counts .val );
216
+ if (attr -> read_format & PERF_FORMAT_TOTAL_TIME_ENABLED )
217
+ __T ("failed to read TOTAL_TIME_ENABLED" , counts .ena );
218
+ if (attr -> read_format & PERF_FORMAT_TOTAL_TIME_RUNNING )
219
+ __T ("failed to read TOTAL_TIME_RUNNING" , counts .run );
220
+ if (attr -> read_format & PERF_FORMAT_ID )
221
+ __T ("failed to read ID" , counts .id );
222
+ if (attr -> read_format & PERF_FORMAT_LOST )
223
+ __T ("failed to read LOST" , counts .lost == 0 );
224
+
225
+ perf_evsel__close (evsel );
226
+ perf_evsel__delete (evsel );
227
+ return 0 ;
228
+ }
229
+
230
+ static int test_stat_read_format_group (struct perf_event_attr * attr , struct perf_thread_map * threads )
231
+ {
232
+ struct perf_evsel * leader , * member ;
233
+ struct perf_counts_values counts ;
234
+ volatile int count = 0x100000 ;
235
+ int err ;
236
+
237
+ attr -> read_format |= PERF_FORMAT_GROUP ;
238
+ leader = perf_evsel__new (attr );
239
+ __T ("failed to create leader" , leader );
240
+
241
+ attr -> read_format &= ~PERF_FORMAT_GROUP ;
242
+ member = perf_evsel__new (attr );
243
+ __T ("failed to create member" , member );
244
+
245
+ member -> leader = leader ;
246
+ leader -> nr_members = 2 ;
247
+
248
+ /* skip old kernels that don't support the format */
249
+ err = perf_evsel__open (leader , NULL , threads );
250
+ if (err < 0 )
251
+ return 0 ;
252
+ err = perf_evsel__open (member , NULL , threads );
253
+ if (err < 0 )
254
+ return 0 ;
255
+
256
+ while (count -- ) ;
257
+
258
+ memset (& counts , -1 , sizeof (counts ));
259
+ perf_evsel__read (leader , 0 , 0 , & counts );
260
+
261
+ __T ("failed to read leader value" , counts .val );
262
+ if (attr -> read_format & PERF_FORMAT_TOTAL_TIME_ENABLED )
263
+ __T ("failed to read leader TOTAL_TIME_ENABLED" , counts .ena );
264
+ if (attr -> read_format & PERF_FORMAT_TOTAL_TIME_RUNNING )
265
+ __T ("failed to read leader TOTAL_TIME_RUNNING" , counts .run );
266
+ if (attr -> read_format & PERF_FORMAT_ID )
267
+ __T ("failed to read leader ID" , counts .id );
268
+ if (attr -> read_format & PERF_FORMAT_LOST )
269
+ __T ("failed to read leader LOST" , counts .lost == 0 );
270
+
271
+ memset (& counts , -1 , sizeof (counts ));
272
+ perf_evsel__read (member , 0 , 0 , & counts );
273
+
274
+ __T ("failed to read member value" , counts .val );
275
+ if (attr -> read_format & PERF_FORMAT_TOTAL_TIME_ENABLED )
276
+ __T ("failed to read member TOTAL_TIME_ENABLED" , counts .ena );
277
+ if (attr -> read_format & PERF_FORMAT_TOTAL_TIME_RUNNING )
278
+ __T ("failed to read member TOTAL_TIME_RUNNING" , counts .run );
279
+ if (attr -> read_format & PERF_FORMAT_ID )
280
+ __T ("failed to read member ID" , counts .id );
281
+ if (attr -> read_format & PERF_FORMAT_LOST )
282
+ __T ("failed to read member LOST" , counts .lost == 0 );
283
+
284
+ perf_evsel__close (member );
285
+ perf_evsel__close (leader );
286
+ perf_evsel__delete (member );
287
+ perf_evsel__delete (leader );
288
+ return 0 ;
289
+ }
290
+
291
+ static int test_stat_read_format (void )
292
+ {
293
+ struct perf_thread_map * threads ;
294
+ struct perf_event_attr attr = {
295
+ .type = PERF_TYPE_SOFTWARE ,
296
+ .config = PERF_COUNT_SW_TASK_CLOCK ,
297
+ };
298
+ int err , i ;
299
+
300
+ #define FMT (_fmt ) PERF_FORMAT_ ## _fmt
301
+ #define FMT_TIME (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
302
+
303
+ uint64_t test_formats [] = {
304
+ 0 ,
305
+ FMT_TIME ,
306
+ FMT (ID ),
307
+ FMT (LOST ),
308
+ FMT_TIME | FMT (ID ),
309
+ FMT_TIME | FMT (LOST ),
310
+ FMT_TIME | FMT (ID ) | FMT (LOST ),
311
+ FMT (ID ) | FMT (LOST ),
312
+ };
313
+
314
+ #undef FMT
315
+ #undef FMT_TIME
316
+
317
+ threads = perf_thread_map__new_dummy ();
318
+ __T ("failed to create threads" , threads );
319
+
320
+ perf_thread_map__set_pid (threads , 0 , 0 );
321
+
322
+ for (i = 0 ; i < (int )ARRAY_SIZE (test_formats ); i ++ ) {
323
+ attr .read_format = test_formats [i ];
324
+ __T_VERBOSE ("testing single read with read_format: %lx\n" ,
325
+ (unsigned long )test_formats [i ]);
326
+
327
+ err = test_stat_read_format_single (& attr , threads );
328
+ __T ("failed to read single format" , err == 0 );
329
+ }
330
+
331
+ perf_thread_map__put (threads );
332
+
333
+ threads = perf_thread_map__new_array (2 , NULL );
334
+ __T ("failed to create threads" , threads );
335
+
336
+ perf_thread_map__set_pid (threads , 0 , 0 );
337
+ perf_thread_map__set_pid (threads , 1 , 0 );
338
+
339
+ for (i = 0 ; i < (int )ARRAY_SIZE (test_formats ); i ++ ) {
340
+ attr .read_format = test_formats [i ];
341
+ __T_VERBOSE ("testing group read with read_format: %lx\n" ,
342
+ (unsigned long )test_formats [i ]);
343
+
344
+ err = test_stat_read_format_group (& attr , threads );
345
+ __T ("failed to read group format" , err == 0 );
346
+ }
347
+
348
+ perf_thread_map__put (threads );
349
+ return 0 ;
350
+ }
351
+
192
352
int test_evsel (int argc , char * * argv )
193
353
{
194
354
__T_START ;
@@ -200,6 +360,7 @@ int test_evsel(int argc, char **argv)
200
360
test_stat_thread_enable ();
201
361
test_stat_user_read (PERF_COUNT_HW_INSTRUCTIONS );
202
362
test_stat_user_read (PERF_COUNT_HW_CPU_CYCLES );
363
+ test_stat_read_format ();
203
364
204
365
__T_END ;
205
366
return tests_failed == 0 ? 0 : -1 ;
0 commit comments