11// SPDX-License-Identifier: GPL-2.0
22#include <stdarg.h>
33#include <stdio.h>
4+ #include <string.h>
45#include <linux/perf_event.h>
6+ #include <linux/kernel.h>
57#include <perf/cpumap.h>
68#include <perf/threadmap.h>
79#include <perf/evsel.h>
10+ #include <internal/evsel.h>
811#include <internal/tests.h>
912#include "tests.h"
1013
@@ -189,6 +192,163 @@ static int test_stat_user_read(int event)
189192 return 0 ;
190193}
191194
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+
192352int test_evsel (int argc , char * * argv )
193353{
194354 __T_START ;
@@ -200,6 +360,7 @@ int test_evsel(int argc, char **argv)
200360 test_stat_thread_enable ();
201361 test_stat_user_read (PERF_COUNT_HW_INSTRUCTIONS );
202362 test_stat_user_read (PERF_COUNT_HW_CPU_CYCLES );
363+ test_stat_read_format ();
203364
204365 __T_END ;
205366 return tests_failed == 0 ? 0 : -1 ;
0 commit comments