mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
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 <namhyung@kernel.org> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://lore.kernel.org/r/20220819003644.508916-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
89e3106fa2
commit
6d395a5135
@ -1,10 +1,13 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <perf/cpumap.h>
|
||||
#include <perf/threadmap.h>
|
||||
#include <perf/evsel.h>
|
||||
#include <internal/evsel.h>
|
||||
#include <internal/tests.h>
|
||||
#include "tests.h"
|
||||
|
||||
@ -189,6 +192,163 @@ static int test_stat_user_read(int event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
struct perf_counts_values counts;
|
||||
volatile int count = 0x100000;
|
||||
int err;
|
||||
|
||||
evsel = perf_evsel__new(attr);
|
||||
__T("failed to create evsel", evsel);
|
||||
|
||||
/* skip old kernels that don't support the format */
|
||||
err = perf_evsel__open(evsel, NULL, threads);
|
||||
if (err < 0)
|
||||
return 0;
|
||||
|
||||
while (count--) ;
|
||||
|
||||
memset(&counts, -1, sizeof(counts));
|
||||
perf_evsel__read(evsel, 0, 0, &counts);
|
||||
|
||||
__T("failed to read value", counts.val);
|
||||
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
|
||||
__T("failed to read TOTAL_TIME_ENABLED", counts.ena);
|
||||
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
|
||||
__T("failed to read TOTAL_TIME_RUNNING", counts.run);
|
||||
if (attr->read_format & PERF_FORMAT_ID)
|
||||
__T("failed to read ID", counts.id);
|
||||
if (attr->read_format & PERF_FORMAT_LOST)
|
||||
__T("failed to read LOST", counts.lost == 0);
|
||||
|
||||
perf_evsel__close(evsel);
|
||||
perf_evsel__delete(evsel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)
|
||||
{
|
||||
struct perf_evsel *leader, *member;
|
||||
struct perf_counts_values counts;
|
||||
volatile int count = 0x100000;
|
||||
int err;
|
||||
|
||||
attr->read_format |= PERF_FORMAT_GROUP;
|
||||
leader = perf_evsel__new(attr);
|
||||
__T("failed to create leader", leader);
|
||||
|
||||
attr->read_format &= ~PERF_FORMAT_GROUP;
|
||||
member = perf_evsel__new(attr);
|
||||
__T("failed to create member", member);
|
||||
|
||||
member->leader = leader;
|
||||
leader->nr_members = 2;
|
||||
|
||||
/* skip old kernels that don't support the format */
|
||||
err = perf_evsel__open(leader, NULL, threads);
|
||||
if (err < 0)
|
||||
return 0;
|
||||
err = perf_evsel__open(member, NULL, threads);
|
||||
if (err < 0)
|
||||
return 0;
|
||||
|
||||
while (count--) ;
|
||||
|
||||
memset(&counts, -1, sizeof(counts));
|
||||
perf_evsel__read(leader, 0, 0, &counts);
|
||||
|
||||
__T("failed to read leader value", counts.val);
|
||||
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
|
||||
__T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);
|
||||
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
|
||||
__T("failed to read leader TOTAL_TIME_RUNNING", counts.run);
|
||||
if (attr->read_format & PERF_FORMAT_ID)
|
||||
__T("failed to read leader ID", counts.id);
|
||||
if (attr->read_format & PERF_FORMAT_LOST)
|
||||
__T("failed to read leader LOST", counts.lost == 0);
|
||||
|
||||
memset(&counts, -1, sizeof(counts));
|
||||
perf_evsel__read(member, 0, 0, &counts);
|
||||
|
||||
__T("failed to read member value", counts.val);
|
||||
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
|
||||
__T("failed to read member TOTAL_TIME_ENABLED", counts.ena);
|
||||
if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
|
||||
__T("failed to read member TOTAL_TIME_RUNNING", counts.run);
|
||||
if (attr->read_format & PERF_FORMAT_ID)
|
||||
__T("failed to read member ID", counts.id);
|
||||
if (attr->read_format & PERF_FORMAT_LOST)
|
||||
__T("failed to read member LOST", counts.lost == 0);
|
||||
|
||||
perf_evsel__close(member);
|
||||
perf_evsel__close(leader);
|
||||
perf_evsel__delete(member);
|
||||
perf_evsel__delete(leader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_stat_read_format(void)
|
||||
{
|
||||
struct perf_thread_map *threads;
|
||||
struct perf_event_attr attr = {
|
||||
.type = PERF_TYPE_SOFTWARE,
|
||||
.config = PERF_COUNT_SW_TASK_CLOCK,
|
||||
};
|
||||
int err, i;
|
||||
|
||||
#define FMT(_fmt) PERF_FORMAT_ ## _fmt
|
||||
#define FMT_TIME (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
|
||||
|
||||
uint64_t test_formats [] = {
|
||||
0,
|
||||
FMT_TIME,
|
||||
FMT(ID),
|
||||
FMT(LOST),
|
||||
FMT_TIME | FMT(ID),
|
||||
FMT_TIME | FMT(LOST),
|
||||
FMT_TIME | FMT(ID) | FMT(LOST),
|
||||
FMT(ID) | FMT(LOST),
|
||||
};
|
||||
|
||||
#undef FMT
|
||||
#undef FMT_TIME
|
||||
|
||||
threads = perf_thread_map__new_dummy();
|
||||
__T("failed to create threads", threads);
|
||||
|
||||
perf_thread_map__set_pid(threads, 0, 0);
|
||||
|
||||
for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
|
||||
attr.read_format = test_formats[i];
|
||||
__T_VERBOSE("testing single read with read_format: %lx\n",
|
||||
(unsigned long)test_formats[i]);
|
||||
|
||||
err = test_stat_read_format_single(&attr, threads);
|
||||
__T("failed to read single format", err == 0);
|
||||
}
|
||||
|
||||
perf_thread_map__put(threads);
|
||||
|
||||
threads = perf_thread_map__new_array(2, NULL);
|
||||
__T("failed to create threads", threads);
|
||||
|
||||
perf_thread_map__set_pid(threads, 0, 0);
|
||||
perf_thread_map__set_pid(threads, 1, 0);
|
||||
|
||||
for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
|
||||
attr.read_format = test_formats[i];
|
||||
__T_VERBOSE("testing group read with read_format: %lx\n",
|
||||
(unsigned long)test_formats[i]);
|
||||
|
||||
err = test_stat_read_format_group(&attr, threads);
|
||||
__T("failed to read group format", err == 0);
|
||||
}
|
||||
|
||||
perf_thread_map__put(threads);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_evsel(int argc, char **argv)
|
||||
{
|
||||
__T_START;
|
||||
@ -200,6 +360,7 @@ int test_evsel(int argc, char **argv)
|
||||
test_stat_thread_enable();
|
||||
test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
|
||||
test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
|
||||
test_stat_read_format();
|
||||
|
||||
__T_END;
|
||||
return tests_failed == 0 ? 0 : -1;
|
||||
|
Loading…
Reference in New Issue
Block a user