Skip to content

Commit 6d395a5

Browse files
namhyungacmel
authored andcommitted
libperf: Add a test case for read formats
It checks a various combination of the read format settings and verify it return the value in a proper position. The test uses task-clock software events to guarantee it's always active and sets enabled/running time. Signed-off-by: Namhyung Kim <[email protected]> Acked-by: Jiri Olsa <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 89e3106 commit 6d395a5

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

tools/lib/perf/tests/test-evsel.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
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+
192352
int 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

Comments
 (0)