Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf tools: Add --pmu-filter option for filtering PMUs

This patch adds a new --pmu-filter option to perf-stat command to allow
filtering events on specific PMUs. This is useful when there are
multiple PMUs with same type (e.g. hisi_sicl2_cpa0 and hisi_sicl0_cpa0).

[root@localhost tmp]# perf stat -M cpa_p0_avg_bw
Performance counter stats for 'system wide':

19,417,779,115 hisi_sicl0_cpa0/cpa_cycles/ # 0.00 cpa_p0_avg_bw
0 hisi_sicl0_cpa0/cpa_p0_wr_dat/
0 hisi_sicl0_cpa0/cpa_p0_rd_dat_64b/
0 hisi_sicl0_cpa0/cpa_p0_rd_dat_32b/
19,417,751,103 hisi_sicl10_cpa0/cpa_cycles/ # 0.00 cpa_p0_avg_bw
0 hisi_sicl10_cpa0/cpa_p0_wr_dat/
0 hisi_sicl10_cpa0/cpa_p0_rd_dat_64b/
0 hisi_sicl10_cpa0/cpa_p0_rd_dat_32b/
19,417,730,679 hisi_sicl2_cpa0/cpa_cycles/ # 0.31 cpa_p0_avg_bw
75,635,749 hisi_sicl2_cpa0/cpa_p0_wr_dat/
18,520,640 hisi_sicl2_cpa0/cpa_p0_rd_dat_64b/
0 hisi_sicl2_cpa0/cpa_p0_rd_dat_32b/
19,417,674,227 hisi_sicl8_cpa0/cpa_cycles/ # 0.00 cpa_p0_avg_bw
0 hisi_sicl8_cpa0/cpa_p0_wr_dat/
0 hisi_sicl8_cpa0/cpa_p0_rd_dat_64b/
0 hisi_sicl8_cpa0/cpa_p0_rd_dat_32b/

19.417734480 seconds time elapsed

[root@localhost tmp]# perf stat --pmu-filter hisi_sicl2_cpa0 -M cpa_p0_avg_bw
Performance counter stats for 'system wide':

6,234,093,559 cpa_cycles # 0.60 cpa_p0_avg_bw
50,548,465 cpa_p0_wr_dat
7,552,182 cpa_p0_rd_dat_64b
0 cpa_p0_rd_dat_32b

6.234139320 seconds time elapsed

Signed-off-by: Qinxin Xia <xiaqinxin@huawei.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Qinxin Xia and committed by
Namhyung Kim
74e2dbe7 e397dd81

+37 -6
+4
tools/perf/Documentation/perf-stat.txt
··· 578 578 Only enable events on applying cpu with this type for hybrid platform 579 579 (e.g. core or atom)" 580 580 581 + --pmu-filter:: 582 + Only enable events on applying pmu with specified for multiple 583 + pmus with same type (e.g. hisi_sicl2_cpa0 or hisi_sicl0_cpa0) 584 + 581 585 EXAMPLES 582 586 -------- 583 587
+19
tools/perf/builtin-stat.c
··· 1214 1214 return 0; 1215 1215 } 1216 1216 1217 + static int parse_pmu_filter(const struct option *opt, 1218 + const char *str, 1219 + int unset __maybe_unused) 1220 + { 1221 + struct evlist *evlist = *(struct evlist **)opt->value; 1222 + 1223 + if (!list_empty(&evlist->core.entries)) { 1224 + fprintf(stderr, "Must define pmu-filter before events/metrics\n"); 1225 + return -1; 1226 + } 1227 + 1228 + parse_events_option_args.pmu_filter = str; 1229 + return 0; 1230 + } 1231 + 1217 1232 static int parse_cache_level(const struct option *opt, 1218 1233 const char *str, 1219 1234 int unset __maybe_unused) ··· 2579 2564 "Only enable events on applying cpu with this type " 2580 2565 "for hybrid platform (e.g. core or atom)", 2581 2566 parse_cputype), 2567 + OPT_CALLBACK(0, "pmu-filter", &evsel_list, "pmu", 2568 + "Only enable events on applying pmu with specified " 2569 + "for multiple pmus with same type(e.g. hisi_sicl2_cpa0 or hisi_sicl0_cpa0)", 2570 + parse_pmu_filter), 2582 2571 #ifdef HAVE_LIBPFM 2583 2572 OPT_CALLBACK(0, "pfm-events", &evsel_list, "event", 2584 2573 "libpfm4 event selector. use 'perf list' to list available events",
+13 -5
tools/perf/util/metricgroup.c
··· 387 387 const char *metric_or_groups) 388 388 { 389 389 const char *pm_pmu = pm->pmu ?: "cpu"; 390 + struct perf_pmu *perf_pmu = NULL; 390 391 391 - if (strcmp(pmu, "all") && strcmp(pm_pmu, pmu)) 392 + if (pm->pmu) 393 + perf_pmu = perf_pmus__find(pm->pmu); 394 + 395 + if (strcmp(pmu, "all") && strcmp(pm_pmu, pmu) && 396 + (perf_pmu && !perf_pmu__name_wildcard_match(perf_pmu, pmu))) 392 397 return false; 393 398 394 399 return match_metric_or_groups(pm->metric_group, metric_or_groups) || ··· 1264 1259 static int parse_ids(bool metric_no_merge, bool fake_pmu, 1265 1260 struct expr_parse_ctx *ids, const char *modifier, 1266 1261 bool group_events, const bool tool_events[TOOL_PMU__EVENT_MAX], 1267 - struct evlist **out_evlist) 1262 + struct evlist **out_evlist, 1263 + const char *filter_pmu) 1268 1264 { 1269 1265 struct parse_events_error parse_error; 1270 1266 struct evlist *parsed_evlist; ··· 1319 1313 } 1320 1314 pr_debug("Parsing metric events '%s'\n", events.buf); 1321 1315 parse_events_error__init(&parse_error); 1322 - ret = __parse_events(parsed_evlist, events.buf, /*pmu_filter=*/NULL, 1316 + ret = __parse_events(parsed_evlist, events.buf, filter_pmu, 1323 1317 &parse_error, fake_pmu, /*warn_if_reordered=*/false, 1324 1318 /*fake_tp=*/false); 1325 1319 if (ret) { ··· 1422 1416 /*modifier=*/NULL, 1423 1417 /*group_events=*/false, 1424 1418 tool_events, 1425 - &combined_evlist); 1419 + &combined_evlist, 1420 + (pmu && strcmp(pmu, "all") == 0) ? NULL : pmu); 1426 1421 } 1427 1422 if (combined) 1428 1423 expr__ctx_free(combined); ··· 1478 1471 } 1479 1472 if (!metric_evlist) { 1480 1473 ret = parse_ids(metric_no_merge, fake_pmu, m->pctx, m->modifier, 1481 - m->group_events, tool_events, &m->evlist); 1474 + m->group_events, tool_events, &m->evlist, 1475 + (pmu && strcmp(pmu, "all") == 0) ? NULL : pmu); 1482 1476 if (ret) 1483 1477 goto out; 1484 1478
+1 -1
tools/perf/util/parse-events.c
··· 429 429 if (parse_state->pmu_filter == NULL) 430 430 return false; 431 431 432 - return strcmp(parse_state->pmu_filter, pmu->name) != 0; 432 + return perf_pmu__wildcard_match(pmu, parse_state->pmu_filter) == 0; 433 433 } 434 434 435 435 static int parse_events_add_pmu(struct parse_events_state *parse_state,