Skip to content

Commit 0a507af

Browse files
olsajiriacmel
authored andcommitted
perf tests: Add parse metric test for ipc metric
Adding new test that process metrics code and checks the expected results. Starting with easy ipc metric. Committer testing: # perf test "Parse and process metrics" 67: Parse and process metrics : Ok # # perf test -v "Parse and process metrics" 67: Parse and process metrics : --- start --- test child forked, pid 103402 metric expr inst_retired.any / cpu_clk_unhalted.thread for IPC found event inst_retired.any found event cpu_clk_unhalted.thread adding {inst_retired.any,cpu_clk_unhalted.thread}:W test child finished with 0 ---- end ---- Parse and process metrics: Ok # Had to fix it to initialize that 'struct value' array sentinel with a named initializer to fix the build with some versions of clang: tests/parse-metric.c:135:7: error: missing field 'val' initializer [-Werror,-Wmissing-field-initializers] { 0 }, Signed-off-by: Jiri Olsa <[email protected]> Acked-by: Ian Rogers <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Michael Petlan <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Link: http://lore.kernel.org/lkml/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 6d432c4 commit 0a507af

File tree

4 files changed

+151
-0
lines changed

4 files changed

+151
-0
lines changed

tools/perf/tests/Build

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ perf-y += genelf.o
5959
perf-y += api-io.o
6060
perf-y += demangle-java-test.o
6161
perf-y += pfm.o
62+
perf-y += parse-metric.o
6263

6364
$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
6465
$(call rule_mkdir)

tools/perf/tests/builtin-test.c

+4
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ static struct test generic_tests[] = {
337337
.desc = "Demangle Java",
338338
.func = test__demangle_java,
339339
},
340+
{
341+
.desc = "Parse and process metrics",
342+
.func = test__parse_metric,
343+
},
340344
{
341345
.func = NULL,
342346
},

tools/perf/tests/parse-metric.c

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/compiler.h>
3+
#include <string.h>
4+
#include <perf/cpumap.h>
5+
#include <perf/evlist.h>
6+
#include "metricgroup.h"
7+
#include "tests.h"
8+
#include "pmu-events/pmu-events.h"
9+
#include "evlist.h"
10+
#include "rblist.h"
11+
#include "debug.h"
12+
#include "expr.h"
13+
#include "stat.h"
14+
15+
static struct pmu_event pme_test[] = {
16+
{
17+
.metric_expr = "inst_retired.any / cpu_clk_unhalted.thread",
18+
.metric_name = "IPC",
19+
},
20+
};
21+
22+
static struct pmu_events_map map = {
23+
.cpuid = "test",
24+
.version = "1",
25+
.type = "core",
26+
.table = pme_test,
27+
};
28+
29+
struct value {
30+
const char *event;
31+
u64 val;
32+
};
33+
34+
static u64 find_value(const char *name, struct value *values)
35+
{
36+
struct value *v = values;
37+
38+
while (v->event) {
39+
if (!strcmp(name, v->event))
40+
return v->val;
41+
v++;
42+
};
43+
return 0;
44+
}
45+
46+
static void load_runtime_stat(struct runtime_stat *st, struct evlist *evlist,
47+
struct value *vals)
48+
{
49+
struct evsel *evsel;
50+
u64 count;
51+
52+
evlist__for_each_entry(evlist, evsel) {
53+
count = find_value(evsel->name, vals);
54+
perf_stat__update_shadow_stats(evsel, count, 0, st);
55+
}
56+
}
57+
58+
static double compute_single(struct rblist *metric_events, struct evlist *evlist,
59+
struct runtime_stat *st)
60+
{
61+
struct evsel *evsel = evlist__first(evlist);
62+
struct metric_event *me;
63+
64+
me = metricgroup__lookup(metric_events, evsel, false);
65+
if (me != NULL) {
66+
struct metric_expr *mexp;
67+
68+
mexp = list_first_entry(&me->head, struct metric_expr, nd);
69+
return test_generic_metric(mexp, 0, st);
70+
}
71+
return 0.;
72+
}
73+
74+
static int compute_metric(const char *name, struct value *vals, double *ratio)
75+
{
76+
struct rblist metric_events = {
77+
.nr_entries = 0,
78+
};
79+
struct perf_cpu_map *cpus;
80+
struct runtime_stat st;
81+
struct evlist *evlist;
82+
int err;
83+
84+
/*
85+
* We need to prepare evlist for stat mode running on CPU 0
86+
* because that's where all the stats are going to be created.
87+
*/
88+
evlist = evlist__new();
89+
if (!evlist)
90+
return -ENOMEM;
91+
92+
cpus = perf_cpu_map__new("0");
93+
if (!cpus)
94+
return -ENOMEM;
95+
96+
perf_evlist__set_maps(&evlist->core, cpus, NULL);
97+
98+
/* Parse the metric into metric_events list. */
99+
err = metricgroup__parse_groups_test(evlist, &map, name,
100+
false, false,
101+
&metric_events);
102+
103+
TEST_ASSERT_VAL("failed to parse metric", err == 0);
104+
105+
if (perf_evlist__alloc_stats(evlist, false))
106+
return -1;
107+
108+
/* Load the runtime stats with given numbers for events. */
109+
runtime_stat__init(&st);
110+
load_runtime_stat(&st, evlist, vals);
111+
112+
/* And execute the metric */
113+
*ratio = compute_single(&metric_events, evlist, &st);
114+
115+
/* ... clenup. */
116+
metricgroup__rblist_exit(&metric_events);
117+
runtime_stat__exit(&st);
118+
perf_evlist__free_stats(evlist);
119+
perf_cpu_map__put(cpus);
120+
evlist__delete(evlist);
121+
return 0;
122+
}
123+
124+
static int test_ipc(void)
125+
{
126+
double ratio;
127+
struct value vals[] = {
128+
{ .event = "inst_retired.any", .val = 300 },
129+
{ .event = "cpu_clk_unhalted.thread", .val = 200 },
130+
{ .event = NULL, },
131+
};
132+
133+
TEST_ASSERT_VAL("failed to compute metric",
134+
compute_metric("IPC", vals, &ratio) == 0);
135+
136+
TEST_ASSERT_VAL("IPC failed, wrong ratio",
137+
ratio == 1.5);
138+
return 0;
139+
}
140+
141+
int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused)
142+
{
143+
TEST_ASSERT_VAL("IPC failed", test_ipc() == 0);
144+
return 0;
145+
}

tools/perf/tests/tests.h

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ int test__demangle_java(struct test *test, int subtest);
121121
int test__pfm(struct test *test, int subtest);
122122
const char *test__pfm_subtest_get_desc(int subtest);
123123
int test__pfm_subtest_get_nr(void);
124+
int test__parse_metric(struct test *test, int subtest);
124125

125126
bool test__bp_signal_is_supported(void);
126127
bool test__bp_account_is_supported(void);

0 commit comments

Comments
 (0)