Introduce 'b' modifier to event parser, which means use BPF program to
manage this event. This is the same as --bpf-counters option, but only
applies to this event. For example,

  perf stat -e cycles:b,cs               # use bpf for cycles, but not cs
  perf stat -e cycles,cs --bpf-counters  # use bpf for both cycles and cs

Suggested-by: Jiri Olsa <jo...@kernel.org>
Signed-off-by: Song Liu <s...@kernel.org>
---
 tools/perf/util/bpf_counter.c  | 2 +-
 tools/perf/util/evsel.h        | 1 +
 tools/perf/util/parse-events.c | 8 +++++++-
 tools/perf/util/parse-events.l | 2 +-
 4 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
index 33b1888103dfa..f179f57430253 100644
--- a/tools/perf/util/bpf_counter.c
+++ b/tools/perf/util/bpf_counter.c
@@ -790,7 +790,7 @@ int bpf_counter__load(struct evsel *evsel, struct target 
*target)
 {
        if (target->bpf_str)
                evsel->bpf_counter_ops = &bpf_program_profiler_ops;
-       else if (target->use_bpf ||
+       else if (target->use_bpf || evsel->bpf_counter ||
                 evsel__match_bpf_counter_events(evsel->name))
                evsel->bpf_counter_ops = &bperf_ops;
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index ce4b629d659c2..8f66cdcb338d0 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -82,6 +82,7 @@ struct evsel {
                bool                    auto_merge_stats;
                bool                    collect_stat;
                bool                    weak_group;
+               bool                    bpf_counter;
                int                     bpf_fd;
                struct bpf_object       *bpf_obj;
        };
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 8123d218ad17c..46ebd269a98d1 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1804,6 +1804,7 @@ struct event_modifier {
        int pinned;
        int weak;
        int exclusive;
+       int bpf_counter;
 };
 
 static int get_event_modifier(struct event_modifier *mod, char *str,
@@ -1824,6 +1825,7 @@ static int get_event_modifier(struct event_modifier *mod, 
char *str,
        int exclude = eu | ek | eh;
        int exclude_GH = evsel ? evsel->exclude_GH : 0;
        int weak = 0;
+       int bpf_counter = 0;
 
        memset(mod, 0, sizeof(*mod));
 
@@ -1867,6 +1869,8 @@ static int get_event_modifier(struct event_modifier *mod, 
char *str,
                        exclusive = 1;
                } else if (*str == 'W') {
                        weak = 1;
+               } else if (*str == 'b') {
+                       bpf_counter = 1;
                } else
                        break;
 
@@ -1898,6 +1902,7 @@ static int get_event_modifier(struct event_modifier *mod, 
char *str,
        mod->sample_read = sample_read;
        mod->pinned = pinned;
        mod->weak = weak;
+       mod->bpf_counter = bpf_counter;
        mod->exclusive = exclusive;
 
        return 0;
@@ -1912,7 +1917,7 @@ static int check_modifier(char *str)
        char *p = str;
 
        /* The sizeof includes 0 byte as well. */
-       if (strlen(str) > (sizeof("ukhGHpppPSDIWe") - 1))
+       if (strlen(str) > (sizeof("ukhGHpppPSDIWeb") - 1))
                return -1;
 
        while (*p) {
@@ -1953,6 +1958,7 @@ int parse_events__modifier_event(struct list_head *list, 
char *str, bool add)
                evsel->sample_read         = mod.sample_read;
                evsel->precise_max         = mod.precise_max;
                evsel->weak_group          = mod.weak;
+               evsel->bpf_counter         = mod.bpf_counter;
 
                if (evsel__is_group_leader(evsel)) {
                        evsel->core.attr.pinned = mod.pinned;
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 0b36285a9435d..fb8646cc3e834 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -210,7 +210,7 @@ name_tag    
[\'][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_*?\.:]+)?
 /* If you add a modifier you need to update check_modifier() */
-modifier_event [ukhpPGHSDIWe]+
+modifier_event [ukhpPGHSDIWeb]+
 modifier_bp    [rwx]{1,3}
 
 %%
-- 
2.30.2

Reply via email to