From: Christy Lee <christylee@fb.com>
To: <andrii@kernel.org>, <acme@kernel.org>, <jolsa@redhat.com>
Cc: <christylee@fb.com>, <christyc.y.lee@gmail.com>,
<bpf@vger.kernel.org>, <linux-perf-users@vger.kernel.org>,
<kernel-team@fb.com>, <wangnan0@huawei.com>,
<bobo.shaobowang@huawei.com>, <yuehaibing@huawei.com>
Subject: [PATCH bpf-next v4 2/2] perf: stop using deprecated bpf_object__next() API
Date: Wed, 19 Jan 2022 15:06:36 -0800 [thread overview]
Message-ID: <20220119230636.1752684-3-christylee@fb.com> (raw)
In-Reply-To: <20220119230636.1752684-1-christylee@fb.com>
Libbpf has deprecated the ability to keep track of object list inside
libbpf, it now requires applications to track usage multiple bpf
objects directly. Remove usage of bpf_object__next() API and hoist the
tracking logic to perf.
Committer note:
This is tested by following the committer's note in the original commit
"aa3abf30bb28addcf593578d37447d42e3f65fc3".
I ran 'perf test -v LLVM' and used it's output to generate a script for
compiling the perf test object:
--------------------------------------------------
$ cat ~/bin/hello-ebpf
INPUT_FILE=/tmp/test.c
OUTPUT_FILE=/tmp/test.o
export KBUILD_DIR=/lib/modules/5.12.0-0_fbk2_3390_g7ecb4ac46d7f/build
export NR_CPUS=56
export LINUX_VERSION_CODE=0x50c00
export CLANG_EXEC=/data/users/christylee/devtools/llvm/latest/bin/clang
export CLANG_OPTIONS=-xc
export KERNEL_INC_OPTIONS="KERNEL_INC_OPTIONS= -nostdinc \
-isystem /usr/lib/gcc/x86_64-redhat-linux/8/include -I./arch/x86/include \
-I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi \
-I./arch/x86/include/generated/uapi -I./include/uapi \
-I./include/generated/uapi -include ./include/linux/compiler-version.h \
-include ./include/linux/kconfig.h"
export PERF_BPF_INC_OPTIONS=-I/usr/lib/perf/include/bpf
export WORKING_DIR=/lib/modules/5.12.0-0_fbk2_3390_g7ecb4ac46d7f/build
export CLANG_SOURCE=-
rm -f $OUTPUT_FILE
cat $INPUT_FILE | /data/users/christylee/devtools/llvm/latest/bin/clang \
-D__KERNEL__ -D__NR_CPUS__=56 -DLINUX_VERSION_CODE=0x50c00 -xc \
-I/usr/lib/perf/include/bpf -nostdinc \
-isystem /usr/lib/gcc/x86_64-redhat-linux/8/include -I./arch/x86/include \
-I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi \
-I./arch/x86/include/generated/uapi -I./include/uapi \
-I./include/generated/uapi -include ./include/linux/compiler-version.h \
-include ./include/linux/kconfig.h -Wno-unused-value -Wno-pointer-sign \
-working-directory /lib/modules/5.12.0-0_fbk2_3390_g7ecb4ac46d7f/build \
-c - -target bpf -O2 -o $OUTPUT_FILE
--------------------------------------------------
I then wrote and compiled a script that ask to get asks to put a probe
at a function that
does not exists in the kernel, it errors out as expected:
$ cat /tmp/test.c
__attribute__((section("probe_point=not_exist"), used))
int probe_point(void *ctx) {
return 0;
}
char _license[] __attribute__((section("license"), used)) = "GPL";
int _version __attribute__((section("version"), used)) = 0x40100;
$ cd ~/bin && ./hello-ebpf
$ ./perf record --event /tmp/test.o sleep 1
Probe point 'not_exist' not found.
event syntax error: '/tmp/test.o'
\___ You need to check probing points in BPF file
(add -v to see detail)
Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list
available events
---------------------------------------------------
Next I changed the attribute to something that exists in the kernel.
As expected, it errors out
with permission problem:
$ cat /tmp/test.c
__attribute__((section("probe_point=kernel_execve"), used))
int probe_point(void *ctx) {
return 0;
}
char _license[] __attribute__((section("license"), used)) = "GPL";
int _version __attribute__((section("version"), used)) = 0x40100;
$ grep kernel_execve /proc/kallsyms
ffffffff812dc210 T kernel_execve
$ cd ~/bin && ./hello-ebpf
$ ./perf record --event /tmp/test.o sleep 1
Failed to open kprobe_events: Permission denied
event syntax error: '/tmp/test.o'
\___ You need to be root
(add -v to see detail)
Run 'perf list' for a list of valid events
Usage: perf record [<options>] [<command>]
or: perf record [<options>] -- <command> [<options>]
-e, --event <event> event selector. use 'perf list' to list
available events
---------------------------------------------------
Reran as root, see that the probe point worked as intended.
$ sudo -i
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.018 MB perf.data ]
perf_bpf_probe:probe_point
perf_bpf_probe:probe_point: type: 2, size: 128, config: 0x8e9, \
{ sample_period, sample_freq }: 1, \
sample_type: IP|TID|TIME|CPU|PERIOD|RAW, read_format: ID, disabled: 1, \
inherit: 1, mmap: 1, comm: 1, enable_on_exec: 1, task: 1, \
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1, ksymbol: 1, \
bpf_event: 1
---------------------------------------------------
Signed-off-by: Christy Lee <christylee@fb.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
---
tools/perf/util/bpf-loader.c | 72 +++++++++++++++++++++++++++---------
tools/perf/util/bpf-loader.h | 1 +
2 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 4631cac3957f..b1822f8af2bb 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -29,9 +29,6 @@
#include <internal/xyarray.h>
-/* temporarily disable libbpf deprecation warnings */
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)),
const char *fmt, va_list args)
{
@@ -49,6 +46,36 @@ struct bpf_prog_priv {
int *type_mapping;
};
+struct bpf_perf_object {
+ struct bpf_object *obj;
+ struct list_head list;
+};
+
+static LIST_HEAD(bpf_objects_list);
+
+struct bpf_perf_object *bpf_perf_object__next(struct bpf_perf_object *prev)
+{
+ struct bpf_perf_object *next;
+
+ if (!prev)
+ next = list_first_entry(&bpf_objects_list,
+ struct bpf_perf_object, list);
+ else
+ next = list_next_entry(prev, list);
+
+ /* Empty list is noticed here so don't need checking on entry. */
+ if (&next->list == &bpf_objects_list)
+ return NULL;
+
+ return next;
+}
+
+#define bpf_perf_object__for_each(perf_obj, tmp, obj) \
+ for ((perf_obj) = bpf_perf_object__next(NULL), \
+ (tmp) = bpf_perf_object__next(perf_obj), (obj) = NULL; \
+ (perf_obj) != NULL; (perf_obj) = (tmp), \
+ (tmp) = bpf_perf_object__next(tmp), (obj) = (perf_obj)->obj)
+
static bool libbpf_initialized;
struct bpf_object *
@@ -113,9 +140,10 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
void bpf__clear(void)
{
- struct bpf_object *obj, *tmp;
+ struct bpf_perf_object *perf_obj, *tmp;
+ struct bpf_object *obj;
- bpf_object__for_each_safe(obj, tmp) {
+ bpf_perf_object__for_each(perf_obj, tmp, obj) {
bpf__unprobe(obj);
bpf_object__close(obj);
}
@@ -621,8 +649,12 @@ static int hook_load_preprocessor(struct bpf_program *prog)
if (err)
return err;
+/* temporarily disable libbpf deprecation warnings */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
err = bpf_program__set_prep(prog, priv->nr_types,
preproc_gen_prologue);
+#pragma GCC diagnostic pop
return err;
}
@@ -776,7 +808,11 @@ int bpf__foreach_event(struct bpf_object *obj,
if (priv->need_prologue) {
int type = priv->type_mapping[i];
+/* temporarily disable libbpf deprecation warnings */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
fd = bpf_program__nth_fd(prog, type);
+#pragma GCC diagnostic pop
} else {
fd = bpf_program__fd(prog);
}
@@ -1488,10 +1524,11 @@ apply_obj_config_object(struct bpf_object *obj)
int bpf__apply_obj_config(void)
{
- struct bpf_object *obj, *tmp;
+ struct bpf_perf_object *perf_obj, *tmp;
+ struct bpf_object *obj;
int err;
- bpf_object__for_each_safe(obj, tmp) {
+ bpf_perf_object__for_each(perf_obj, tmp, obj) {
err = apply_obj_config_object(obj);
if (err)
return err;
@@ -1500,26 +1537,25 @@ int bpf__apply_obj_config(void)
return 0;
}
-#define bpf__for_each_map(pos, obj, objtmp) \
- bpf_object__for_each_safe(obj, objtmp) \
- bpf_object__for_each_map(pos, obj)
+#define bpf__perf_for_each_map(perf_obj, tmp, obj, map) \
+ bpf_perf_object__for_each(perf_obj, tmp, obj) \
+ bpf_object__for_each_map(map, obj)
-#define bpf__for_each_map_named(pos, obj, objtmp, name) \
- bpf__for_each_map(pos, obj, objtmp) \
- if (bpf_map__name(pos) && \
- (strcmp(name, \
- bpf_map__name(pos)) == 0))
+#define bpf__perf_for_each_map_named(perf_obj, tmp, obj, map, name) \
+ bpf__perf_for_each_map(perf_obj, tmp, obj, map) \
+ if (bpf_map__name(map) && (strcmp(name, bpf_map__name(map)) == 0))
struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
{
struct bpf_map_priv *tmpl_priv = NULL;
- struct bpf_object *obj, *tmp;
+ struct bpf_perf_object *perf_obj, *tmp;
+ struct bpf_object *obj;
struct evsel *evsel = NULL;
struct bpf_map *map;
int err;
bool need_init = false;
- bpf__for_each_map_named(map, obj, tmp, name) {
+ bpf__perf_for_each_map_named(perf_obj, tmp, obj, map, name) {
struct bpf_map_priv *priv = bpf_map__priv(map);
if (IS_ERR(priv))
@@ -1555,7 +1591,7 @@ struct evsel *bpf__setup_output_event(struct evlist *evlist, const char *name)
evsel = evlist__last(evlist);
}
- bpf__for_each_map_named(map, obj, tmp, name) {
+ bpf__perf_for_each_map_named(perf_obj, tmp, obj, map, name) {
struct bpf_map_priv *priv = bpf_map__priv(map);
if (IS_ERR(priv))
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index 5d1c725cea29..95262b7e936f 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -53,6 +53,7 @@ typedef int (*bpf_prog_iter_callback_t)(const char *group, const char *event,
#ifdef HAVE_LIBBPF_SUPPORT
struct bpf_object *bpf__prepare_load(const char *filename, bool source);
+struct bpf_perf_object *bpf_perf_object__next(struct bpf_perf_object *prev);
int bpf__strerror_prepare_load(const char *filename, bool source,
int err, char *buf, size_t size);
--
2.30.2
next prev parent reply other threads:[~2022-01-19 23:09 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-19 23:06 [PATCH bpf-next v4 0/2] perf: stop using deprecated bpf APIs Christy Lee
2022-01-19 23:06 ` [PATCH bpf-next v4 1/2] perf: stop using deprecated bpf_load_program() API Christy Lee
2022-01-19 23:25 ` Andrii Nakryiko
[not found] ` <C02B00A0-5760-44CE-B727-90CF601A8437@fb.com>
2022-01-19 23:26 ` Andrii Nakryiko
[not found] ` <D753C41C-A70A-4316-8201-9F8369D1E627@fb.com>
2022-01-20 1:01 ` Andrii Nakryiko
2022-01-19 23:06 ` Christy Lee [this message]
2022-01-19 23:23 ` [PATCH bpf-next v4 2/2] perf: stop using deprecated bpf_object__next() API Song Liu
2022-01-23 17:06 ` Jiri Olsa
2022-02-02 17:00 ` Jiri Olsa
2022-02-02 17:24 ` Christy Lee
2022-02-09 16:11 ` Andrii Nakryiko
2022-02-12 7:31 ` Andrii Nakryiko
2022-01-20 22:58 ` [PATCH bpf-next v4 0/2] perf: stop using deprecated bpf APIs Andrii Nakryiko
2022-01-22 20:01 ` Arnaldo Carvalho de Melo
2022-01-22 20:38 ` Arnaldo Carvalho de Melo
2022-01-22 21:07 ` Arnaldo Carvalho de Melo
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=20220119230636.1752684-3-christylee@fb.com \
--to=christylee@fb.com \
--cc=acme@kernel.org \
--cc=andrii@kernel.org \
--cc=bobo.shaobowang@huawei.com \
--cc=bpf@vger.kernel.org \
--cc=christyc.y.lee@gmail.com \
--cc=jolsa@redhat.com \
--cc=kernel-team@fb.com \
--cc=linux-perf-users@vger.kernel.org \
--cc=wangnan0@huawei.com \
--cc=yuehaibing@huawei.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.