2024-05-24 21:00:32

by Ian Rogers

[permalink] [raw]
Subject: [PATCH v3 0/3] Use BPF filters for a "perf top -u" workaround

Allow uid and gid to be terms in BPF filters by first breaking the
connection between filter terms and PERF_SAMPLE_xx values. Calculate
the uid and gid using the bpf_get_current_uid_gid helper, rather than
from a value in the sample. Allow filters to be passed to perf top, this allows:

$ perf top -e cycles:P --filter "uid == $(id -u)"

to work as a "perf top -u" workaround, as "perf top -u" usually fails
due to processes/threads terminating between the /proc scan and the
perf_event_open.

v3. Move PERF_SAMPLE_xx asserts to sample_filter.bpf.c to avoid
conflicting definitions between vmlinux.h and perf_event.h as
reported by Namhyung.
v2. Allow PERF_SAMPLE_xx to be computed from the PBF_TERM_xx value
using a shift as requested by Namhyung.

Ian Rogers (3):
perf bpf filter: Give terms their own enum
perf bpf filter: Add uid and gid terms
perf top: Allow filters on events

tools/perf/Documentation/perf-record.txt | 2 +-
tools/perf/Documentation/perf-top.txt | 4 ++
tools/perf/builtin-top.c | 9 +++
tools/perf/util/bpf-filter.c | 33 +++++----
tools/perf/util/bpf-filter.h | 5 +-
tools/perf/util/bpf-filter.l | 66 +++++++++---------
tools/perf/util/bpf-filter.y | 7 +-
tools/perf/util/bpf_skel/sample-filter.h | 40 ++++++++++-
tools/perf/util/bpf_skel/sample_filter.bpf.c | 73 +++++++++++++++-----
9 files changed, 169 insertions(+), 70 deletions(-)

--
2.45.1.288.g0e0cd299f1-goog



2024-05-24 21:01:37

by Ian Rogers

[permalink] [raw]
Subject: [PATCH v3 3/3] perf top: Allow filters on events

Allow filters to be added to perf top events. One use is to workaround
issues with:
```
$ perf top --uid="$(id -u)"
```
which tries to scan /proc find processes belonging to the uid and can
fail in such a pid terminates between the scan and the
perf_event_open reporting:
```
Error:
The sys_perf_event_open() syscall returned with 3 (No such process) for event (cycles:P).
/bin/dmesg | grep -i perf may provide additional information.
```
A similar filter:
```
$ perf top -e cycles:P --filter "uid == $(id -u)"
```
doesn't fail this way.

Signed-off-by: Ian Rogers <[email protected]>
---
tools/perf/Documentation/perf-top.txt | 4 ++++
tools/perf/builtin-top.c | 9 +++++++++
2 files changed, 13 insertions(+)

diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index a754875fa5bb..667e5102075e 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -43,6 +43,10 @@ Default is to monitor all CPUS.
encoding with the layout of the event control registers as described
by entries in /sys/bus/event_source/devices/cpu/format/*.

+--filter=<filter>::
+ Event filter. This option should follow an event selector (-e). For
+ syntax see linkperf:perf-record[1].
+
-E <entries>::
--entries=<entries>::
Display this many functions.
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1d6aef51c122..e8cbbf10d361 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1055,6 +1055,13 @@ static int perf_top__start_counters(struct perf_top *top)
}
}

+ if (evlist__apply_filters(evlist, &counter)) {
+ pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n",
+ counter->filter ?: "BPF", evsel__name(counter), errno,
+ str_error_r(errno, msg, sizeof(msg)));
+ goto out_err;
+ }
+
if (evlist__mmap(evlist, opts->mmap_pages) < 0) {
ui__error("Failed to mmap with %d (%s)\n",
errno, str_error_r(errno, msg, sizeof(msg)));
@@ -1462,6 +1469,8 @@ int cmd_top(int argc, const char **argv)
OPT_CALLBACK('e', "event", &parse_events_option_args, "event",
"event selector. use 'perf list' to list available events",
parse_events_option),
+ OPT_CALLBACK(0, "filter", &top.evlist, "filter",
+ "event filter", parse_filter),
OPT_U64('c', "count", &opts->user_interval, "event period to sample"),
OPT_STRING('p', "pid", &target->pid, "pid",
"profile events on existing process id"),
--
2.45.1.288.g0e0cd299f1-goog


2024-05-30 06:04:19

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] Use BPF filters for a "perf top -u" workaround

On Fri, May 24, 2024 at 1:52 PM Ian Rogers <[email protected]> wrote:
>
> Allow uid and gid to be terms in BPF filters by first breaking the
> connection between filter terms and PERF_SAMPLE_xx values. Calculate
> the uid and gid using the bpf_get_current_uid_gid helper, rather than
> from a value in the sample. Allow filters to be passed to perf top, this allows:
>
> $ perf top -e cycles:P --filter "uid == $(id -u)"
>
> to work as a "perf top -u" workaround, as "perf top -u" usually fails
> due to processes/threads terminating between the /proc scan and the
> perf_event_open.
>
> v3. Move PERF_SAMPLE_xx asserts to sample_filter.bpf.c to avoid
> conflicting definitions between vmlinux.h and perf_event.h as
> reported by Namhyung.
> v2. Allow PERF_SAMPLE_xx to be computed from the PBF_TERM_xx value
> using a shift as requested by Namhyung.
>
> Ian Rogers (3):
> perf bpf filter: Give terms their own enum
> perf bpf filter: Add uid and gid terms
> perf top: Allow filters on events

Acked-by: Namhyung Kim <[email protected]>

Thanks,
Namhyung

>
> tools/perf/Documentation/perf-record.txt | 2 +-
> tools/perf/Documentation/perf-top.txt | 4 ++
> tools/perf/builtin-top.c | 9 +++
> tools/perf/util/bpf-filter.c | 33 +++++----
> tools/perf/util/bpf-filter.h | 5 +-
> tools/perf/util/bpf-filter.l | 66 +++++++++---------
> tools/perf/util/bpf-filter.y | 7 +-
> tools/perf/util/bpf_skel/sample-filter.h | 40 ++++++++++-
> tools/perf/util/bpf_skel/sample_filter.bpf.c | 73 +++++++++++++++-----
> 9 files changed, 169 insertions(+), 70 deletions(-)
>
> --
> 2.45.1.288.g0e0cd299f1-goog
>

2024-05-31 21:16:32

by Namhyung Kim

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] Use BPF filters for a "perf top -u" workaround

On Fri, 24 May 2024 13:52:24 -0700, Ian Rogers wrote:
> Allow uid and gid to be terms in BPF filters by first breaking the
> connection between filter terms and PERF_SAMPLE_xx values. Calculate
> the uid and gid using the bpf_get_current_uid_gid helper, rather than
> from a value in the sample. Allow filters to be passed to perf top, this allows:
>
> $ perf top -e cycles:P --filter "uid == $(id -u)"
>
> [...]

Applied to perf-tools-next, thanks!

[1/3] perf bpf filter: Give terms their own enum
commit: 63b9cbd7941aa9ec5cb61567042176c4ce04b020
[2/3] perf bpf filter: Add uid and gid terms
commit: d92aa899fe0a66350303a1986d6dc7ec4b3a1ea7
[3/3] perf top: Allow filters on events
commit: af752016340021d433a962063067e819dba889b1

Best regards,
--
Namhyung Kim <[email protected]>