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
committed by Arnaldo Carvalho de Melo
parent ea66536ab2
commit b2b9d3a3f0
4 changed files with 33 additions and 4 deletions

View File

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