Skip to content

Commit

Permalink
perf metric: Add --metric-no-threshold option
Browse files Browse the repository at this point in the history
Thresholds may need additional events, this can impact things like
sharing groups of events to avoid multiplexing. Add a flag to make the
threshold calculations optional. The threshold will still be computed
if no additional events are necessary.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Caleb Biggers <caleb.biggers@intel.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Florian Fischer <florian.fischer@muhq.space>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Perry Taylor <perry.taylor@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Link: https://lore.kernel.org/r/20230219092848.639226-39-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Ian Rogers authored and Arnaldo Carvalho de Melo committed Feb 19, 2023
1 parent 7980293 commit 1fd09e2
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 32 deletions.
4 changes: 4 additions & 0 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,8 @@ static struct option stat_options[] = {
"don't group metric events, impacts multiplexing"),
OPT_BOOLEAN(0, "metric-no-merge", &stat_config.metric_no_merge,
"don't try to share events between metrics in a group"),
OPT_BOOLEAN(0, "metric-no-threshold", &stat_config.metric_no_threshold,
"don't try to share events between metrics in a group "),
OPT_BOOLEAN(0, "topdown", &topdown_run,
"measure top-down statistics"),
OPT_UINTEGER(0, "td-level", &stat_config.topdown_level,
Expand Down Expand Up @@ -1852,6 +1854,7 @@ static int add_default_attributes(void)
return metricgroup__parse_groups(evsel_list, "transaction",
stat_config.metric_no_group,
stat_config.metric_no_merge,
stat_config.metric_no_threshold,
stat_config.user_requested_cpu_list,
stat_config.system_wide,
&stat_config.metric_events);
Expand Down Expand Up @@ -2519,6 +2522,7 @@ int cmd_stat(int argc, const char **argv)
metricgroup__parse_groups(evsel_list, metrics,
stat_config.metric_no_group,
stat_config.metric_no_merge,
stat_config.metric_no_threshold,
stat_config.user_requested_cpu_list,
stat_config.system_wide,
&stat_config.metric_events);
Expand Down
3 changes: 1 addition & 2 deletions tools/perf/tests/expand-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ static int expand_metric_events(void)

rblist__init(&metric_events);
pme_test = find_core_metrics_table("testarch", "testcpu");
ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str,
false, false, &metric_events);
ret = metricgroup__parse_groups_test(evlist, pme_test, metric_str, &metric_events);
if (ret < 0) {
pr_debug("failed to parse '%s' metric\n", metric_str);
goto out;
Expand Down
1 change: 0 additions & 1 deletion tools/perf/tests/parse-metric.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ static int __compute_metric(const char *name, struct value *vals,
/* Parse the metric into metric_events list. */
pme_test = find_core_metrics_table("testarch", "testcpu");
err = metricgroup__parse_groups_test(evlist, pme_test, name,
false, false,
&metric_events);
if (err)
goto out;
Expand Down
4 changes: 1 addition & 3 deletions tools/perf/tests/pmu-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,9 +846,7 @@ static int test__parsing_callback(const struct pmu_metric *pm,
perf_evlist__set_maps(&evlist->core, cpus, NULL);
runtime_stat__init(&st);

err = metricgroup__parse_groups_test(evlist, table, pm->metric_name,
false, false,
&metric_events);
err = metricgroup__parse_groups_test(evlist, table, pm->metric_name, &metric_events);
if (err) {
if (!strcmp(pm->metric_name, "M1") || !strcmp(pm->metric_name, "M2") ||
!strcmp(pm->metric_name, "M3")) {
Expand Down
62 changes: 39 additions & 23 deletions tools/perf/util/metricgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ struct metricgroup_add_iter_data {
int *ret;
bool *has_match;
bool metric_no_group;
bool metric_no_threshold;
const char *user_requested_cpu_list;
bool system_wide;
struct metric *root_metric;
Expand All @@ -786,6 +787,7 @@ static int add_metric(struct list_head *metric_list,
const struct pmu_metric *pm,
const char *modifier,
bool metric_no_group,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct metric *root_metric,
Expand Down Expand Up @@ -813,6 +815,7 @@ static int add_metric(struct list_head *metric_list,
static int resolve_metric(struct list_head *metric_list,
const char *modifier,
bool metric_no_group,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct metric *root_metric,
Expand Down Expand Up @@ -861,8 +864,8 @@ static int resolve_metric(struct list_head *metric_list,
*/
for (i = 0; i < pending_cnt; i++) {
ret = add_metric(metric_list, &pending[i].pm, modifier, metric_no_group,
user_requested_cpu_list, system_wide, root_metric, visited,
table);
metric_no_threshold, user_requested_cpu_list, system_wide,
root_metric, visited, table);
if (ret)
break;
}
Expand All @@ -879,6 +882,7 @@ static int resolve_metric(struct list_head *metric_list,
* @metric_no_group: Should events written to events be grouped "{}" or
* global. Grouping is the default but due to multiplexing the
* user may override.
* @metric_no_threshold: Should threshold expressions be ignored?
* @runtime: A special argument for the parser only known at runtime.
* @user_requested_cpu_list: Command line specified CPUs to record on.
* @system_wide: Are events for all processes recorded.
Expand All @@ -894,6 +898,7 @@ static int __add_metric(struct list_head *metric_list,
const struct pmu_metric *pm,
const char *modifier,
bool metric_no_group,
bool metric_no_threshold,
int runtime,
const char *user_requested_cpu_list,
bool system_wide,
Expand Down Expand Up @@ -974,10 +979,12 @@ static int __add_metric(struct list_head *metric_list,
* Threshold expressions are built off the actual metric. Switch
* to use that in case of additional necessary events. Change
* the visited node name to avoid this being flagged as
* recursion.
* recursion. If the threshold events are disabled, just use the
* metric's name as a reference. This allows metric threshold
* computation if there are sufficient events.
*/
assert(strstr(pm->metric_threshold, pm->metric_name));
expr = pm->metric_threshold;
expr = metric_no_threshold ? pm->metric_name : pm->metric_threshold;
visited_node.name = "__threshold__";
}
if (expr__find_ids(expr, NULL, root_metric->pctx) < 0) {
Expand All @@ -987,8 +994,8 @@ static int __add_metric(struct list_head *metric_list,
if (!ret) {
/* Resolve referenced metrics. */
ret = resolve_metric(metric_list, modifier, metric_no_group,
user_requested_cpu_list, system_wide,
root_metric, &visited_node, table);
metric_no_threshold, user_requested_cpu_list,
system_wide, root_metric, &visited_node, table);
}
if (ret) {
if (is_root)
Expand Down Expand Up @@ -1035,6 +1042,7 @@ static int add_metric(struct list_head *metric_list,
const struct pmu_metric *pm,
const char *modifier,
bool metric_no_group,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct metric *root_metric,
Expand All @@ -1046,9 +1054,9 @@ static int add_metric(struct list_head *metric_list,
pr_debug("metric expr %s for %s\n", pm->metric_expr, pm->metric_name);

if (!strstr(pm->metric_expr, "?")) {
ret = __add_metric(metric_list, pm, modifier, metric_no_group, 0,
user_requested_cpu_list, system_wide, root_metric,
visited, table);
ret = __add_metric(metric_list, pm, modifier, metric_no_group,
metric_no_threshold, 0, user_requested_cpu_list,
system_wide, root_metric, visited, table);
} else {
int j, count;

Expand All @@ -1060,9 +1068,9 @@ static int add_metric(struct list_head *metric_list,
*/

for (j = 0; j < count && !ret; j++)
ret = __add_metric(metric_list, pm, modifier, metric_no_group, j,
user_requested_cpu_list, system_wide,
root_metric, visited, table);
ret = __add_metric(metric_list, pm, modifier, metric_no_group,
metric_no_threshold, j, user_requested_cpu_list,
system_wide, root_metric, visited, table);
}

return ret;
Expand All @@ -1079,8 +1087,8 @@ static int metricgroup__add_metric_sys_event_iter(const struct pmu_metric *pm,
return 0;

ret = add_metric(d->metric_list, pm, d->modifier, d->metric_no_group,
d->user_requested_cpu_list, d->system_wide,
d->root_metric, d->visited, d->table);
d->metric_no_threshold, d->user_requested_cpu_list,
d->system_wide, d->root_metric, d->visited, d->table);
if (ret)
goto out;

Expand Down Expand Up @@ -1124,6 +1132,7 @@ struct metricgroup__add_metric_data {
const char *modifier;
const char *user_requested_cpu_list;
bool metric_no_group;
bool metric_no_threshold;
bool system_wide;
bool has_match;
};
Expand All @@ -1141,8 +1150,9 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,

data->has_match = true;
ret = add_metric(data->list, pm, data->modifier, data->metric_no_group,
data->user_requested_cpu_list, data->system_wide,
/*root_metric=*/NULL, /*visited_metrics=*/NULL, table);
data->metric_no_threshold, data->user_requested_cpu_list,
data->system_wide, /*root_metric=*/NULL,
/*visited_metrics=*/NULL, table);
}
return ret;
}
Expand All @@ -1163,7 +1173,7 @@ static int metricgroup__add_metric_callback(const struct pmu_metric *pm,
* architecture perf is running upon.
*/
static int metricgroup__add_metric(const char *metric_name, const char *modifier,
bool metric_no_group,
bool metric_no_group, bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct list_head *metric_list,
Expand All @@ -1179,6 +1189,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier
.metric_name = metric_name,
.modifier = modifier,
.metric_no_group = metric_no_group,
.metric_no_threshold = metric_no_threshold,
.user_requested_cpu_list = user_requested_cpu_list,
.system_wide = system_wide,
.has_match = false,
Expand Down Expand Up @@ -1241,6 +1252,7 @@ static int metricgroup__add_metric(const char *metric_name, const char *modifier
* architecture perf is running upon.
*/
static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide, struct list_head *metric_list,
const struct pmu_metrics_table *table)
Expand All @@ -1259,7 +1271,8 @@ static int metricgroup__add_metric_list(const char *list, bool metric_no_group,
*modifier++ = '\0';

ret = metricgroup__add_metric(metric_name, modifier,
metric_no_group, user_requested_cpu_list,
metric_no_group, metric_no_threshold,
user_requested_cpu_list,
system_wide, metric_list, table);
if (ret == -EINVAL)
pr_err("Cannot find metric or group `%s'\n", metric_name);
Expand Down Expand Up @@ -1449,6 +1462,7 @@ static int parse_ids(bool metric_no_merge, struct perf_pmu *fake_pmu,
static int parse_groups(struct evlist *perf_evlist, const char *str,
bool metric_no_group,
bool metric_no_merge,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct perf_pmu *fake_pmu,
Expand All @@ -1463,7 +1477,7 @@ static int parse_groups(struct evlist *perf_evlist, const char *str,

if (metric_events_list->nr_entries == 0)
metricgroup__rblist_init(metric_events_list);
ret = metricgroup__add_metric_list(str, metric_no_group,
ret = metricgroup__add_metric_list(str, metric_no_group, metric_no_threshold,
user_requested_cpu_list,
system_wide, &metric_list, table);
if (ret)
Expand Down Expand Up @@ -1598,6 +1612,7 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
const char *str,
bool metric_no_group,
bool metric_no_merge,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct rblist *metric_events)
Expand All @@ -1608,18 +1623,19 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
return -EINVAL;

return parse_groups(perf_evlist, str, metric_no_group, metric_no_merge,
user_requested_cpu_list, system_wide,
metric_no_threshold, user_requested_cpu_list, system_wide,
/*fake_pmu=*/NULL, metric_events, table);
}

int metricgroup__parse_groups_test(struct evlist *evlist,
const struct pmu_metrics_table *table,
const char *str,
bool metric_no_group,
bool metric_no_merge,
struct rblist *metric_events)
{
return parse_groups(evlist, str, metric_no_group, metric_no_merge,
return parse_groups(evlist, str,
/*metric_no_group=*/false,
/*metric_no_merge=*/false,
/*metric_no_threshold=*/false,
/*user_requested_cpu_list=*/NULL,
/*system_wide=*/false,
&perf_pmu__fake, metric_events, table);
Expand Down
3 changes: 1 addition & 2 deletions tools/perf/util/metricgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,13 @@ int metricgroup__parse_groups(struct evlist *perf_evlist,
const char *str,
bool metric_no_group,
bool metric_no_merge,
bool metric_no_threshold,
const char *user_requested_cpu_list,
bool system_wide,
struct rblist *metric_events);
int metricgroup__parse_groups_test(struct evlist *evlist,
const struct pmu_metrics_table *table,
const char *str,
bool metric_no_group,
bool metric_no_merge,
struct rblist *metric_events);

void metricgroup__print(const struct print_callbacks *print_cb, void *print_state);
Expand Down
3 changes: 2 additions & 1 deletion tools/perf/util/stat-shadow.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,8 @@ static void generic_metric(struct perf_stat_config *config,
char metric_bf[64];

if (metric_threshold &&
expr__parse(&threshold, pctx, metric_threshold) == 0) {
expr__parse(&threshold, pctx, metric_threshold) == 0 &&
!isnan(threshold)) {
color = fpclassify(threshold) == FP_ZERO
? PERF_COLOR_GREEN : PERF_COLOR_RED;
}
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ struct perf_stat_config {
bool no_csv_summary;
bool metric_no_group;
bool metric_no_merge;
bool metric_no_threshold;
bool stop_read_counter;
bool iostat_run;
char *user_requested_cpu_list;
Expand Down

0 comments on commit 1fd09e2

Please sign in to comment.