forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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]>
- Loading branch information
Showing
4 changed files
with
151 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
#include <linux/compiler.h> | ||
#include <string.h> | ||
#include <perf/cpumap.h> | ||
#include <perf/evlist.h> | ||
#include "metricgroup.h" | ||
#include "tests.h" | ||
#include "pmu-events/pmu-events.h" | ||
#include "evlist.h" | ||
#include "rblist.h" | ||
#include "debug.h" | ||
#include "expr.h" | ||
#include "stat.h" | ||
|
||
static struct pmu_event pme_test[] = { | ||
{ | ||
.metric_expr = "inst_retired.any / cpu_clk_unhalted.thread", | ||
.metric_name = "IPC", | ||
}, | ||
}; | ||
|
||
static struct pmu_events_map map = { | ||
.cpuid = "test", | ||
.version = "1", | ||
.type = "core", | ||
.table = pme_test, | ||
}; | ||
|
||
struct value { | ||
const char *event; | ||
u64 val; | ||
}; | ||
|
||
static u64 find_value(const char *name, struct value *values) | ||
{ | ||
struct value *v = values; | ||
|
||
while (v->event) { | ||
if (!strcmp(name, v->event)) | ||
return v->val; | ||
v++; | ||
}; | ||
return 0; | ||
} | ||
|
||
static void load_runtime_stat(struct runtime_stat *st, struct evlist *evlist, | ||
struct value *vals) | ||
{ | ||
struct evsel *evsel; | ||
u64 count; | ||
|
||
evlist__for_each_entry(evlist, evsel) { | ||
count = find_value(evsel->name, vals); | ||
perf_stat__update_shadow_stats(evsel, count, 0, st); | ||
} | ||
} | ||
|
||
static double compute_single(struct rblist *metric_events, struct evlist *evlist, | ||
struct runtime_stat *st) | ||
{ | ||
struct evsel *evsel = evlist__first(evlist); | ||
struct metric_event *me; | ||
|
||
me = metricgroup__lookup(metric_events, evsel, false); | ||
if (me != NULL) { | ||
struct metric_expr *mexp; | ||
|
||
mexp = list_first_entry(&me->head, struct metric_expr, nd); | ||
return test_generic_metric(mexp, 0, st); | ||
} | ||
return 0.; | ||
} | ||
|
||
static int compute_metric(const char *name, struct value *vals, double *ratio) | ||
{ | ||
struct rblist metric_events = { | ||
.nr_entries = 0, | ||
}; | ||
struct perf_cpu_map *cpus; | ||
struct runtime_stat st; | ||
struct evlist *evlist; | ||
int err; | ||
|
||
/* | ||
* We need to prepare evlist for stat mode running on CPU 0 | ||
* because that's where all the stats are going to be created. | ||
*/ | ||
evlist = evlist__new(); | ||
if (!evlist) | ||
return -ENOMEM; | ||
|
||
cpus = perf_cpu_map__new("0"); | ||
if (!cpus) | ||
return -ENOMEM; | ||
|
||
perf_evlist__set_maps(&evlist->core, cpus, NULL); | ||
|
||
/* Parse the metric into metric_events list. */ | ||
err = metricgroup__parse_groups_test(evlist, &map, name, | ||
false, false, | ||
&metric_events); | ||
|
||
TEST_ASSERT_VAL("failed to parse metric", err == 0); | ||
|
||
if (perf_evlist__alloc_stats(evlist, false)) | ||
return -1; | ||
|
||
/* Load the runtime stats with given numbers for events. */ | ||
runtime_stat__init(&st); | ||
load_runtime_stat(&st, evlist, vals); | ||
|
||
/* And execute the metric */ | ||
*ratio = compute_single(&metric_events, evlist, &st); | ||
|
||
/* ... clenup. */ | ||
metricgroup__rblist_exit(&metric_events); | ||
runtime_stat__exit(&st); | ||
perf_evlist__free_stats(evlist); | ||
perf_cpu_map__put(cpus); | ||
evlist__delete(evlist); | ||
return 0; | ||
} | ||
|
||
static int test_ipc(void) | ||
{ | ||
double ratio; | ||
struct value vals[] = { | ||
{ .event = "inst_retired.any", .val = 300 }, | ||
{ .event = "cpu_clk_unhalted.thread", .val = 200 }, | ||
{ .event = NULL, }, | ||
}; | ||
|
||
TEST_ASSERT_VAL("failed to compute metric", | ||
compute_metric("IPC", vals, &ratio) == 0); | ||
|
||
TEST_ASSERT_VAL("IPC failed, wrong ratio", | ||
ratio == 1.5); | ||
return 0; | ||
} | ||
|
||
int test__parse_metric(struct test *test __maybe_unused, int subtest __maybe_unused) | ||
{ | ||
TEST_ASSERT_VAL("IPC failed", test_ipc() == 0); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters