[PATCH v4 03/10] perf parse-events: Add parse_uid_filter helper

Ian Rogers posted 10 patches 6 months, 2 weeks ago
[PATCH v4 03/10] perf parse-events: Add parse_uid_filter helper
Posted by Ian Rogers 6 months, 2 weeks ago
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>
---
 tools/perf/util/parse-events.c | 33 ++++++++++++++++++++++++++++++++-
 tools/perf/util/parse-events.h |  1 +
 2 files changed, 33 insertions(+), 1 deletion(-)

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..46e5a01be61c 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -45,6 +45,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 {
-- 
2.50.0.rc0.604.gd4ff7b7c86-goog
Re: [PATCH v4 03/10] perf parse-events: Add parse_uid_filter helper
Posted by Namhyung Kim 6 months, 2 weeks ago
Hi Ian,

On Wed, Jun 04, 2025 at 10:45:37AM -0700, Ian Rogers wrote:
> 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>
> ---
>  tools/perf/util/parse-events.c | 33 ++++++++++++++++++++++++++++++++-
>  tools/perf/util/parse-events.h |  1 +
>  2 files changed, 33 insertions(+), 1 deletion(-)
> 
> 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)

It failed to build on alpine 3.18.

util/parse-events.h:48:45: error: unknown type name 'uid_t'                     
   48 | int parse_uid_filter(struct evlist *evlist, uid_t uid);                 
      |                                             ^~~~~

I'll add this.

Thanks,
Namhyung


---8<---
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index ab242f6710313993..931780911e071ec6 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;



> +{
> +	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..46e5a01be61c 100644
> --- a/tools/perf/util/parse-events.h
> +++ b/tools/perf/util/parse-events.h
> @@ -45,6 +45,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 {
> -- 
> 2.50.0.rc0.604.gd4ff7b7c86-goog
>
Re: [PATCH v4 03/10] perf parse-events: Add parse_uid_filter helper
Posted by Ian Rogers 6 months, 2 weeks ago
On Fri, Jun 6, 2025 at 10:41 AM Namhyung Kim <namhyung@kernel.org> wrote:
>
> Hi Ian,
>
> On Wed, Jun 04, 2025 at 10:45:37AM -0700, Ian Rogers wrote:
> > 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>
> > ---
> >  tools/perf/util/parse-events.c | 33 ++++++++++++++++++++++++++++++++-
> >  tools/perf/util/parse-events.h |  1 +
> >  2 files changed, 33 insertions(+), 1 deletion(-)
> >
> > 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)
>
> It failed to build on alpine 3.18.
>
> util/parse-events.h:48:45: error: unknown type name 'uid_t'
>    48 | int parse_uid_filter(struct evlist *evlist, uid_t uid);
>       |                                             ^~~~~
>
> I'll add this.

Thanks Namhyung! I see this in tmp.perf-tools-next so I'll assume
there's no need for a v5.

Ian

> Thanks,
> Namhyung
>
>
> ---8<---
> diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
> index ab242f6710313993..931780911e071ec6 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;
>
>
>
> > +{
> > +     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..46e5a01be61c 100644
> > --- a/tools/perf/util/parse-events.h
> > +++ b/tools/perf/util/parse-events.h
> > @@ -45,6 +45,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 {
> > --
> > 2.50.0.rc0.604.gd4ff7b7c86-goog
> >
Re: [PATCH v4 03/10] perf parse-events: Add parse_uid_filter helper
Posted by Namhyung Kim 6 months, 2 weeks ago
On Fri, Jun 06, 2025 at 11:13:10AM -0700, Ian Rogers wrote:
> On Fri, Jun 6, 2025 at 10:41 AM Namhyung Kim <namhyung@kernel.org> wrote:
> >
> > Hi Ian,
> >
> > On Wed, Jun 04, 2025 at 10:45:37AM -0700, Ian Rogers wrote:
> > > 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>
> > > ---
> > >  tools/perf/util/parse-events.c | 33 ++++++++++++++++++++++++++++++++-
> > >  tools/perf/util/parse-events.h |  1 +
> > >  2 files changed, 33 insertions(+), 1 deletion(-)
> > >
> > > 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)
> >
> > It failed to build on alpine 3.18.
> >
> > util/parse-events.h:48:45: error: unknown type name 'uid_t'
> >    48 | int parse_uid_filter(struct evlist *evlist, uid_t uid);
> >       |                                             ^~~~~
> >
> > I'll add this.
> 
> Thanks Namhyung! I see this in tmp.perf-tools-next so I'll assume
> there's no need for a v5.

Right, I've updated the branch with the fix.

Thanks,
Namhyung