OSDN Git Service

perf stat: Enable counting events for BPF programs
authorSong Liu <songliubraving@fb.com>
Tue, 29 Dec 2020 21:42:14 +0000 (13:42 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 20 Jan 2021 17:25:28 +0000 (14:25 -0300)
commitfa853c4b839ece9cd589e8858819240933cc4d78
treeb1cfceea97cad873a3a5d1642e1c2f3e195e0314
parentfbcdaa1908e8f61aa56c71a1db9a9deb72110a9d
perf stat: Enable counting events for BPF programs

Introduce 'perf stat -b' option, which counts events for BPF programs, like:

  [root@localhost ~]# ~/perf stat -e ref-cycles,cycles -b 254 -I 1000
     1.487903822            115,200      ref-cycles
     1.487903822             86,012      cycles
     2.489147029             80,560      ref-cycles
     2.489147029             73,784      cycles
     3.490341825             60,720      ref-cycles
     3.490341825             37,797      cycles
     4.491540887             37,120      ref-cycles
     4.491540887             31,963      cycles

The example above counts 'cycles' and 'ref-cycles' of BPF program of id
254.  This is similar to bpftool-prog-profile command, but more
flexible.

'perf stat -b' creates per-cpu perf_event and loads fentry/fexit BPF
programs (monitor-progs) to the target BPF program (target-prog). The
monitor-progs read perf_event before and after the target-prog, and
aggregate the difference in a BPF map. Then the user space reads data
from these maps.

A new 'struct bpf_counter' is introduced to provide a common interface
that uses BPF programs/maps to count perf events.

Committer notes:

Removed all but bpf_counter.h includes from evsel.h, not needed at all.

Also BPF map lookups for PERCPU_ARRAYs need to have as its value receive
buffer passed to the kernel libbpf_num_possible_cpus() entries, not
evsel__nr_cpus(evsel), as the former uses
/sys/devices/system/cpu/possible while the later uses
/sys/devices/system/cpu/online, which may be less than the 'possible'
number making the bpf map lookup overwrite memory and cause hard to
debug memory corruption.

We need to continue using evsel__nr_cpus(evsel) when accessing the
perf_counts array tho, not to overwrite another are of memory :-)

Signed-off-by: Song Liu <songliubraving@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/lkml/20210120163031.GU12699@kernel.org/
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: kernel-team@fb.com
Link: http://lore.kernel.org/lkml/20201229214214.3413833-4-songliubraving@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
14 files changed:
tools/perf/Documentation/perf-stat.txt
tools/perf/Makefile.perf
tools/perf/builtin-stat.c
tools/perf/util/Build
tools/perf/util/bpf_counter.c [new file with mode: 0644]
tools/perf/util/bpf_counter.h [new file with mode: 0644]
tools/perf/util/bpf_skel/bpf_prog_profiler.bpf.c [new file with mode: 0644]
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/python.c
tools/perf/util/stat-display.c
tools/perf/util/stat.c
tools/perf/util/target.c
tools/perf/util/target.h