perf pmu: Support wildcards on pmu name in dynamic pmu events

Starting on v4.12 event parsing code for dynamic pmu events already
supports prefix-based matching of multiple pmus when creating dynamic
events. E.g., in a system with the following dynamic pmus:

    mypmu_0
    mypmu_1
    mypmu_2
    mypmu_4

passing mypmu/<config>/ as an event spec will result in the creation of
the event in all of the pmus. This change expands this matching through
the use of fnmatch so glob-like expressions can be used to create events
in multiple pmus. E.g., in the system described above if a user only
wants to create the event in mypmu_0 and mypmu_1, mypmu_[01]/<config>/
can be passed.

Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org>
Acked-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Timur Tabi <timur@codeaurora.org>
Change-Id: Icb25653fc5d5239c20f3bffdfdf4ab4c9c9bb20b
Link: http://lkml.kernel.org/r/1520454947-16977-1-git-send-email-agustinv@codeaurora.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Agustin Vega-Frias 2018-03-06 09:04:42 -05:00 коммит произвёл Arnaldo Carvalho de Melo
Родитель ea66536ab2
Коммит b2b9d3a3f0
4 изменённых файлов: 33 добавлений и 4 удалений

Просмотреть файл

@ -141,7 +141,13 @@ on the first memory controller on socket 0 of a Intel Xeon system
Each memory controller has its own PMU. Measuring the complete system Each memory controller has its own PMU. Measuring the complete system
bandwidth would require specifying all imc PMUs (see perf list output), bandwidth would require specifying all imc PMUs (see perf list output),
and adding the values together. and adding the values together. To simplify creation of multiple events,
prefix and glob matching is supported in the PMU name, and the prefix
'uncore_' is also ignored when performing the match. So the command above
can be expanded to all memory controllers by using the syntaxes:
perf stat -C 0 -a imc/cas_count_read/,imc/cas_count_write/ -I 1000 ...
perf stat -C 0 -a *imc*/cas_count_read/,*imc*/cas_count_write/ -I 1000 ...
This example measures the combined core power every second This example measures the combined core power every second

Просмотреть файл

@ -49,6 +49,13 @@ report::
parameters are defined by corresponding entries in parameters are defined by corresponding entries in
/sys/bus/event_source/devices/<pmu>/format/* /sys/bus/event_source/devices/<pmu>/format/*
Note that the last two syntaxes support prefix and glob matching in
the PMU name to simplify creation of events accross multiple instances
of the same type of PMU in large systems (e.g. memory controller PMUs).
Multiple PMU instances are typical for uncore PMUs, so the prefix
'uncore_' is also ignored when performing this match.
-i:: -i::
--no-inherit:: --no-inherit::
child tasks do not inherit counters child tasks do not inherit counters
@ -260,6 +267,12 @@ taskset.
--no-merge:: --no-merge::
Do not merge results from same PMUs. Do not merge results from same PMUs.
When multiple events are created from a single event alias, stat will,
by default, aggregate the event counts and show the result in a single
row. This option disables that behavior and shows the individual events
and counts. Aliases are listed immediately after the Kernel PMU events
by perf list.
--smi-cost:: --smi-cost::
Measure SMI cost if msr/aperf/ and msr/smi/ events are supported. Measure SMI cost if msr/aperf/ and msr/smi/ events are supported.

Просмотреть файл

@ -175,7 +175,7 @@ bpf_source [^,{}]+\.c[a-zA-Z0-9._]*
num_dec [0-9]+ num_dec [0-9]+
num_hex 0x[a-fA-F0-9]+ num_hex 0x[a-fA-F0-9]+
num_raw_hex [a-fA-F0-9]+ num_raw_hex [a-fA-F0-9]+
name [a-zA-Z_*?][a-zA-Z0-9_*?.]* name [a-zA-Z_*?\[\]][a-zA-Z0-9_*?.\[\]]*
name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?.:]* name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?.:]*
drv_cfg_term [a-zA-Z0-9_\.]+(=[a-zA-Z0-9_*?\.:]+)? drv_cfg_term [a-zA-Z0-9_\.]+(=[a-zA-Z0-9_*?\.:]+)?
/* If you add a modifier you need to update check_modifier() */ /* If you add a modifier you need to update check_modifier() */

Просмотреть файл

@ -8,6 +8,7 @@
#define YYDEBUG 1 #define YYDEBUG 1
#include <fnmatch.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/types.h> #include <linux/types.h>
@ -234,6 +235,10 @@ PE_NAME opt_event_config
if (parse_events_add_pmu(_parse_state, list, $1, $2)) { if (parse_events_add_pmu(_parse_state, list, $1, $2)) {
struct perf_pmu *pmu = NULL; struct perf_pmu *pmu = NULL;
int ok = 0; int ok = 0;
char *pattern;
if (asprintf(&pattern, "%s*", $1) < 0)
YYABORT;
while ((pmu = perf_pmu__scan(pmu)) != NULL) { while ((pmu = perf_pmu__scan(pmu)) != NULL) {
char *name = pmu->name; char *name = pmu->name;
@ -241,14 +246,19 @@ PE_NAME opt_event_config
if (!strncmp(name, "uncore_", 7) && if (!strncmp(name, "uncore_", 7) &&
strncmp($1, "uncore_", 7)) strncmp($1, "uncore_", 7))
name += 7; name += 7;
if (!strncmp($1, name, strlen($1))) { if (!fnmatch(pattern, name, 0)) {
if (parse_events_copy_term_list(orig_terms, &terms)) if (parse_events_copy_term_list(orig_terms, &terms)) {
free(pattern);
YYABORT; YYABORT;
}
if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms)) if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms))
ok++; ok++;
parse_events_terms__delete(terms); parse_events_terms__delete(terms);
} }
} }
free(pattern);
if (!ok) if (!ok)
YYABORT; YYABORT;
} }