diff options
author | Ian Rogers <irogers@google.com> | 2025-06-04 10:45:37 -0700 |
---|---|---|
committer | Namhyung Kim <namhyung@kernel.org> | 2025-06-09 11:18:17 -0700 |
commit | 466db4275edd35b7a9af7c82575bcb3289f2c9c0 (patch) | |
tree | 68672c6d65f5417afd2b733bcf39323d6c11466e | |
parent | 5ddf4c3a17dc499fcbaf35692bc894340062dee8 (diff) |
perf parse-events: Add parse_uid_filter helper
Add parse_uid_filter filter as a helper to parse_filter, that
constructs a uid filter string. As uid filters don't work with
tracepoint filters, add a is_possible_tp_filter function so the
tracepoint filter isn't attempted for tracepoint evsels.
Signed-off-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250604174545.2853620-4-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
-rw-r--r-- | tools/perf/util/parse-events.c | 33 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 2 |
2 files changed, 34 insertions, 1 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d96adf23dc94..7f34e602fc08 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -25,6 +25,7 @@ #include "pmu.h" #include "pmus.h" #include "asm/bug.h" +#include "ui/ui.h" #include "util/parse-branch-options.h" #include "util/evsel_config.h" #include "util/event.h" @@ -2561,6 +2562,12 @@ foreach_evsel_in_last_glob(struct evlist *evlist, return 0; } +/* Will a tracepoint filter work for str or should a BPF filter be used? */ +static bool is_possible_tp_filter(const char *str) +{ + return strstr(str, "uid") == NULL; +} + static int set_filter(struct evsel *evsel, const void *arg) { const char *str = arg; @@ -2573,7 +2580,7 @@ static int set_filter(struct evsel *evsel, const void *arg) return -1; } - if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) { + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT && is_possible_tp_filter(str)) { if (evsel__append_tp_filter(evsel, str) < 0) { fprintf(stderr, "not enough memory to hold filter string\n"); @@ -2609,6 +2616,30 @@ int parse_filter(const struct option *opt, const char *str, (const void *)str); } +int parse_uid_filter(struct evlist *evlist, uid_t uid) +{ + struct option opt = { + .value = &evlist, + }; + char buf[128]; + int ret; + + snprintf(buf, sizeof(buf), "uid == %d", uid); + ret = parse_filter(&opt, buf, /*unset=*/0); + if (ret) { + if (use_browser >= 1) { + /* + * Use ui__warning so a pop up appears above the + * underlying BPF error message. + */ + ui__warning("Failed to add UID filtering that uses BPF filtering.\n"); + } else { + fprintf(stderr, "Failed to add UID filtering that uses BPF filtering.\n"); + } + } + return ret; +} + static int add_exclude_perf_filter(struct evsel *evsel, const void *arg __maybe_unused) { diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index ab242f671031..1c20ed0879aa 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -11,6 +11,7 @@ #include <linux/perf_event.h> #include <stdio.h> #include <string.h> +#include <sys/types.h> struct evsel; struct evlist; @@ -45,6 +46,7 @@ static inline int parse_events(struct evlist *evlist, const char *str, int parse_event(struct evlist *evlist, const char *str); int parse_filter(const struct option *opt, const char *str, int unset); +int parse_uid_filter(struct evlist *evlist, uid_t uid); int exclude_perf(const struct option *opt, const char *arg, int unset); enum parse_events__term_val_type { |