From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
Cc: Song Liu <songliubraving@fb.com>,
linux-kernel <linux-kernel@vger.kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Mark Rutland <mark.rutland@arm.com>, Jiri Olsa <jolsa@redhat.com>,
kernel-team@fb.com
Subject: Re: [PATCH v6 2/4] perf: support build BPF skeletons with perf
Date: Tue, 29 Dec 2020 08:48:28 -0300 [thread overview]
Message-ID: <20201229114828.GG521329@kernel.org> (raw)
In-Reply-To: <CAM9d7chjWMFNeQMBftu725cTbCRauUJinQSqy9E9itv=AJXvyA@mail.gmail.com>
Em Tue, Dec 29, 2020 at 04:01:41PM +0900, Namhyung Kim escreveu:
> On Tue, Dec 29, 2020 at 2:41 AM Song Liu <songliubraving@fb.com> wrote:
> > BPF programs are useful in perf to profile BPF programs. BPF skeleton is
> I'm having difficulties understanding the first sentence - looks like a
> recursion. :) So do you want to use two (or more) BPF programs?
Yeah, we use perf to perf perf, so we need to use bpf with perf to perf
bpf :-)
Look at tools/perf/util/bpf_skel/bpf_prog_profiler.bpf.c, the BPF
skeleton used to create the in-kernel scaffold to profile BPF programs.
It uses two BPF programs (fentry/XXX and fexit/XXX) and some a
PERF_EVENT_ARRAY map and an array to diff counters read at exit from
counters read at exit of the profiled BPF programs and then accumulate
those diffs in another PERCPU_ARRAY.
This all ends up composing a "BPF PMU" that is what the userspace perf
tooling will read (from "accum_readings" BPF map) and 'perf stat' will
consume as if reading from an "old style perf counter" :-)
Song, did I get it right? :-)
For convenience, it is below:
- Arnaldo
[acme@five perf]$ cat tools/perf/util/bpf_skel/bpf_prog_profiler.bpf.c
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
// Copyright (c) 2020 Facebook
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
/* map of perf event fds, num_cpu * num_metric entries */
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(int));
} events SEC(".maps");
/* readings at fentry */
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(struct bpf_perf_event_value));
__uint(max_entries, 1);
} fentry_readings SEC(".maps");
/* accumulated readings */
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(struct bpf_perf_event_value));
__uint(max_entries, 1);
} accum_readings SEC(".maps");
const volatile __u32 num_cpu = 1;
SEC("fentry/XXX")
int BPF_PROG(fentry_XXX)
{
__u32 key = bpf_get_smp_processor_id();
struct bpf_perf_event_value *ptr;
__u32 zero = 0;
long err;
/* look up before reading, to reduce error */
ptr = bpf_map_lookup_elem(&fentry_readings, &zero);
if (!ptr)
return 0;
err = bpf_perf_event_read_value(&events, key, ptr, sizeof(*ptr));
if (err)
return 0;
return 0;
}
static inline void
fexit_update_maps(struct bpf_perf_event_value *after)
{
struct bpf_perf_event_value *before, diff, *accum;
__u32 zero = 0;
before = bpf_map_lookup_elem(&fentry_readings, &zero);
/* only account samples with a valid fentry_reading */
if (before && before->counter) {
struct bpf_perf_event_value *accum;
diff.counter = after->counter - before->counter;
diff.enabled = after->enabled - before->enabled;
diff.running = after->running - before->running;
accum = bpf_map_lookup_elem(&accum_readings, &zero);
if (accum) {
accum->counter += diff.counter;
accum->enabled += diff.enabled;
accum->running += diff.running;
}
}
}
SEC("fexit/XXX")
int BPF_PROG(fexit_XXX)
{
struct bpf_perf_event_value reading;
__u32 cpu = bpf_get_smp_processor_id();
__u32 one = 1, zero = 0;
int err;
/* read all events before updating the maps, to reduce error */
err = bpf_perf_event_read_value(&events, cpu, &reading, sizeof(reading));
if (err)
return 0;
fexit_update_maps(&reading);
return 0;
}
char LICENSE[] SEC("license") = "Dual BSD/GPL";
[acme@five perf]$
next prev parent reply other threads:[~2020-12-29 11:49 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-28 17:40 [PATCH v6 0/4] Introduce perf-stat -b for BPF programs Song Liu
2020-12-28 17:40 ` [PATCH v6 1/4] bpftool: add Makefile target bootstrap Song Liu
2020-12-28 17:40 ` [PATCH v6 2/4] perf: support build BPF skeletons with perf Song Liu
2020-12-29 7:01 ` Namhyung Kim
2020-12-29 11:48 ` Arnaldo Carvalho de Melo [this message]
2020-12-29 17:14 ` Song Liu
2020-12-29 18:16 ` Arnaldo Carvalho de Melo
2020-12-28 17:40 ` [PATCH v6 3/4] perf-stat: enable counting events for BPF programs Song Liu
2020-12-28 20:11 ` Arnaldo Carvalho de Melo
2020-12-28 23:43 ` Song Liu
2020-12-29 5:53 ` Song Liu
2020-12-29 15:15 ` Arnaldo Carvalho de Melo
2020-12-29 18:42 ` Song Liu
2020-12-29 18:48 ` Arnaldo Carvalho de Melo
2020-12-29 19:11 ` Song Liu
2020-12-29 19:18 ` Arnaldo Carvalho de Melo
2020-12-29 19:23 ` Arnaldo Carvalho de Melo
2020-12-29 19:32 ` Arnaldo Carvalho de Melo
2020-12-29 21:40 ` Song Liu
2020-12-29 7:22 ` Namhyung Kim
2020-12-29 17:46 ` Song Liu
2020-12-29 17:59 ` Song Liu
2020-12-28 17:40 ` [PATCH v6 4/4] perf-stat: add documentation for -b option Song Liu
2020-12-29 7:24 ` Namhyung Kim
2020-12-29 16:59 ` Song Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201229114828.GG521329@kernel.org \
--to=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=jolsa@redhat.com \
--cc=kernel-team@fb.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=songliubraving@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.