summaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-list.txt1
-rw-r--r--tools/perf/util/parse-events.c11
-rw-r--r--tools/perf/util/parse-events.l3
3 files changed, 13 insertions, 2 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index eb03f063f0a2..6fce6a622206 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -30,6 +30,7 @@ counted. The following modifiers exist:
H - host counting (not in KVM guests)
p - precise level
S - read sample value (PERF_SAMPLE_READ)
+ D - pin the event to the PMU
The 'p' modifier can be used for specifying how precise the instruction
address should be. The 'p' modifier can be specified multiple times:
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index dba877dc9482..9cba92386a82 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -688,6 +688,7 @@ struct event_modifier {
int precise;
int exclude_GH;
int sample_read;
+ int pinned;
};
static int get_event_modifier(struct event_modifier *mod, char *str,
@@ -700,6 +701,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
int eG = evsel ? evsel->attr.exclude_guest : 0;
int precise = evsel ? evsel->attr.precise_ip : 0;
int sample_read = 0;
+ int pinned = evsel ? evsel->attr.pinned : 0;
int exclude = eu | ek | eh;
int exclude_GH = evsel ? evsel->exclude_GH : 0;
@@ -734,6 +736,8 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
eG = 1;
} else if (*str == 'S') {
sample_read = 1;
+ } else if (*str == 'D') {
+ pinned = 1;
} else
break;
@@ -761,6 +765,8 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
mod->precise = precise;
mod->exclude_GH = exclude_GH;
mod->sample_read = sample_read;
+ mod->pinned = pinned;
+
return 0;
}
@@ -773,7 +779,7 @@ static int check_modifier(char *str)
char *p = str;
/* The sizeof includes 0 byte as well. */
- if (strlen(str) > (sizeof("ukhGHpppS") - 1))
+ if (strlen(str) > (sizeof("ukhGHpppSD") - 1))
return -1;
while (*p) {
@@ -812,6 +818,9 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
evsel->attr.exclude_guest = mod.eG;
evsel->exclude_GH = mod.exclude_GH;
evsel->sample_read = mod.sample_read;
+
+ if (perf_evsel__is_group_leader(evsel))
+ evsel->attr.pinned = mod.pinned;
}
return 0;
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index b36115fe416a..0790452658b3 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -82,7 +82,8 @@ num_hex 0x[a-fA-F0-9]+
num_raw_hex [a-fA-F0-9]+
name [a-zA-Z_*?][a-zA-Z0-9_*?]*
name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?]*
-modifier_event [ukhpGHS]+
+/* If you add a modifier you need to update check_modifier() */
+modifier_event [ukhpGHSD]+
modifier_bp [rwx]{1,3}
%%