* [PATCH v2 bpf-next 0/4] libbpf: deprecate bpf_program__get_prog_info_linear @ 2021-10-11 8:20 Dave Marchevsky 2021-10-11 8:20 ` [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear Dave Marchevsky ` (3 more replies) 0 siblings, 4 replies; 13+ messages in thread From: Dave Marchevsky @ 2021-10-11 8:20 UTC (permalink / raw) To: bpf, linux-perf-users Cc: Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar, Dave Marchevsky bpf_program__get_prog_info_linear is a helper which wraps the bpf_obj_get_info_by_fd BPF syscall with some niceties that put all dynamic-length bpf_prog_info in one buffer contiguous with struct bpf_prog_info, and simplify the selection of which dynamic data to grab. The resultant combined struct, bpf_prog_info_linear, is persisted to file by 'perf' to enable later annotation of BPF prog data. libbpf includes some vaddr <-> offset conversion helpers for struct bpf_prog_info_linear to simplify this. This functionality is heavily tailored to perf's usecase, so its use as a general prog info API should be deemphasized in favor of just calling bpf_obj_get_info_by_fd, which can be more easily fit to purpose. Some examples from caller migrations in this series: * Some callers weren't requesting or using dynamic-sized prog info and are well served by a simple get_info_by_fd call (e.g. dump_prog_id_as_func_ptr in bpftool) * Some callers were requesting all of a specific dynamic info type but only using the first record, so can avoid unnecessary malloc by only requesting 1 (e.g. profile_target_name in bpftool) * bpftool's do_dump saves some malloc/free by growing and reusing its dynamic prog_info buf as it loops over progs to grab info and dump. Perf does need the full functionality of bpf_program__get_prog_info_linear and its accompanying structs + helpers, so copy the code to its codebase, migrate all other uses in the tree, and deprecate the helper in libbpf. Since the deprecated symbols continue to be included in perf some renaming was necessary in perf's copy, otherwise functionality is unchanged. This work was previously discussed in libbpf's issue tracker [0]. [0]: https://github.com/libbpf/libbpf/issues/313 v1->v2: fix bpftool do_dump changes to clear bpf_prog_info after use and correctly pass realloc'd ptr back (patch 2) Dave Marchevsky (4): libbpf: migrate internal use of bpf_program__get_prog_info_linear bpftool: use bpf_obj_get_info_by_fd directly perf: pull in bpf_program__get_prog_info_linear libbpf: deprecate bpf_program__get_prog_info_linear tools/bpf/bpftool/btf_dumper.c | 40 +-- tools/bpf/bpftool/prog.c | 154 ++++++++--- tools/lib/bpf/libbpf.c | 15 +- tools/lib/bpf/libbpf.h | 3 + .../Documentation/perf.data-file-format.txt | 2 +- tools/perf/util/Build | 1 + tools/perf/util/annotate.c | 3 +- tools/perf/util/bpf-event.c | 41 ++- tools/perf/util/bpf-event.h | 2 +- tools/perf/util/bpf-utils.c | 261 ++++++++++++++++++ tools/perf/util/bpf-utils.h | 76 +++++ tools/perf/util/bpf_counter.c | 6 +- tools/perf/util/dso.c | 1 + tools/perf/util/env.c | 1 + tools/perf/util/header.c | 13 +- 15 files changed, 527 insertions(+), 92 deletions(-) create mode 100644 tools/perf/util/bpf-utils.c create mode 100644 tools/perf/util/bpf-utils.h -- 2.30.2 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear 2021-10-11 8:20 [PATCH v2 bpf-next 0/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky @ 2021-10-11 8:20 ` Dave Marchevsky 2021-10-20 17:36 ` Andrii Nakryiko 2021-10-11 8:20 ` [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly Dave Marchevsky ` (2 subsequent siblings) 3 siblings, 1 reply; 13+ messages in thread From: Dave Marchevsky @ 2021-10-11 8:20 UTC (permalink / raw) To: bpf, linux-perf-users Cc: Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar, Dave Marchevsky In preparation for bpf_program__get_prog_info_linear, move the single use in libbpf to call bpf_obj_get_info_by_fd directly. Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> --- tools/lib/bpf/libbpf.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index ed313fd491bd..8b86c4831aa8 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8459,26 +8459,24 @@ int libbpf_find_vmlinux_btf_id(const char *name, static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) { - struct bpf_prog_info_linear *info_linear; - struct bpf_prog_info *info; + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); struct btf *btf; int err; - info_linear = bpf_program__get_prog_info_linear(attach_prog_fd, 0); - err = libbpf_get_error(info_linear); + err = bpf_obj_get_info_by_fd(attach_prog_fd, &info, &info_len); if (err) { - pr_warn("failed get_prog_info_linear for FD %d\n", + pr_warn("failed bpf_obj_get_info_by_fd for FD %d\n", attach_prog_fd); return err; } err = -EINVAL; - info = &info_linear->info; - if (!info->btf_id) { + if (!info.btf_id) { pr_warn("The target program doesn't have BTF\n"); goto out; } - btf = btf__load_from_kernel_by_id(info->btf_id); + btf = btf__load_from_kernel_by_id(info.btf_id); if (libbpf_get_error(btf)) { pr_warn("Failed to get BTF of the program\n"); goto out; @@ -8490,7 +8488,6 @@ static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) goto out; } out: - free(info_linear); return err; } -- 2.30.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear 2021-10-11 8:20 ` [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear Dave Marchevsky @ 2021-10-20 17:36 ` Andrii Nakryiko 0 siblings, 0 replies; 13+ messages in thread From: Andrii Nakryiko @ 2021-10-20 17:36 UTC (permalink / raw) To: Dave Marchevsky Cc: bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > > In preparation for bpf_program__get_prog_info_linear, move the single for bpf_program__get_prog_info_linear *deprecation* ? fixed it up while applying > use in libbpf to call bpf_obj_get_info_by_fd directly. > > Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > --- I've applied this patch for now, as it is pretty independent (and I've already fixed it up already and didn't want to lose that :) I hope you don't mind. > tools/lib/bpf/libbpf.c | 15 ++++++--------- > 1 file changed, 6 insertions(+), 9 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index ed313fd491bd..8b86c4831aa8 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -8459,26 +8459,24 @@ int libbpf_find_vmlinux_btf_id(const char *name, > > static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) > { > - struct bpf_prog_info_linear *info_linear; > - struct bpf_prog_info *info; > + struct bpf_prog_info info = {}; > + __u32 info_len = sizeof(info); > struct btf *btf; > int err; > > - info_linear = bpf_program__get_prog_info_linear(attach_prog_fd, 0); > - err = libbpf_get_error(info_linear); > + err = bpf_obj_get_info_by_fd(attach_prog_fd, &info, &info_len); > if (err) { > - pr_warn("failed get_prog_info_linear for FD %d\n", > + pr_warn("failed bpf_obj_get_info_by_fd for FD %d\n", I've also added err code into warn message here > attach_prog_fd); > return err; > } > > err = -EINVAL; > - info = &info_linear->info; > - if (!info->btf_id) { > + if (!info.btf_id) { > pr_warn("The target program doesn't have BTF\n"); > goto out; > } > - btf = btf__load_from_kernel_by_id(info->btf_id); > + btf = btf__load_from_kernel_by_id(info.btf_id); > if (libbpf_get_error(btf)) { > pr_warn("Failed to get BTF of the program\n"); and here > goto out; > @@ -8490,7 +8488,6 @@ static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) > goto out; > } > out: > - free(info_linear); > return err; > } > > -- > 2.30.2 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly 2021-10-11 8:20 [PATCH v2 bpf-next 0/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-11 8:20 ` [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear Dave Marchevsky @ 2021-10-11 8:20 ` Dave Marchevsky 2021-10-20 17:37 ` Andrii Nakryiko 2021-10-11 8:20 ` [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-11 8:20 ` [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky 3 siblings, 1 reply; 13+ messages in thread From: Dave Marchevsky @ 2021-10-11 8:20 UTC (permalink / raw) To: bpf, linux-perf-users Cc: Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar, Dave Marchevsky To prepare for impending deprecation of libbpf's bpf_program__get_prog_info_linear, migrate uses of this function to use bpf_obj_get_info_by_fd. Since the profile_target_name and dump_prog_id_as_func_ptr helpers were only looking at the first func_info, avoid grabbing the rest to save a malloc. For do_dump, add a more full-featured helper, but avoid free/realloc of buffer when possible for multi-prog dumps. Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> --- tools/bpf/bpftool/btf_dumper.c | 40 +++++---- tools/bpf/bpftool/prog.c | 154 +++++++++++++++++++++++++-------- 2 files changed, 144 insertions(+), 50 deletions(-) diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 9c25286a5c73..0f85704628bf 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c @@ -32,14 +32,16 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, const struct btf_type *func_proto, __u32 prog_id) { - struct bpf_prog_info_linear *prog_info = NULL; const struct btf_type *func_type; + int prog_fd = -1, func_sig_len; + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); const char *prog_name = NULL; - struct bpf_func_info *finfo; struct btf *prog_btf = NULL; - struct bpf_prog_info *info; - int prog_fd, func_sig_len; + struct bpf_func_info finfo; + __u32 finfo_rec_size; char prog_str[1024]; + int err; /* Get the ptr's func_proto */ func_sig_len = btf_dump_func(d->btf, prog_str, func_proto, NULL, 0, @@ -55,22 +57,27 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, if (prog_fd == -1) goto print; - prog_info = bpf_program__get_prog_info_linear(prog_fd, - 1UL << BPF_PROG_INFO_FUNC_INFO); - close(prog_fd); - if (IS_ERR(prog_info)) { - prog_info = NULL; + err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); + if (err) goto print; - } - info = &prog_info->info; - if (!info->btf_id || !info->nr_func_info) + if (!info.btf_id || !info.nr_func_info) + goto print; + + finfo_rec_size = info.func_info_rec_size; + memset(&info, 0, sizeof(info)); + info.nr_func_info = 1; + info.func_info_rec_size = finfo_rec_size; + info.func_info = ptr_to_u64(&finfo); + + err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); + if (err) goto print; - prog_btf = btf__load_from_kernel_by_id(info->btf_id); + + prog_btf = btf__load_from_kernel_by_id(info.btf_id); if (libbpf_get_error(prog_btf)) goto print; - finfo = u64_to_ptr(info->func_info); - func_type = btf__type_by_id(prog_btf, finfo->type_id); + func_type = btf__type_by_id(prog_btf, finfo.type_id); if (!func_type || !btf_is_func(func_type)) goto print; @@ -92,7 +99,8 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, prog_str[sizeof(prog_str) - 1] = '\0'; jsonw_string(d->jw, prog_str); btf__free(prog_btf); - free(prog_info); + if (prog_fd != -1) + close(prog_fd); return 0; } diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index a24ea7e26aa4..3b3ccc7b6dd4 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -98,6 +98,72 @@ static enum bpf_attach_type parse_attach_type(const char *str) return __MAX_BPF_ATTACH_TYPE; } +#define holder_prep_needed_rec_sz(nr, rec_size)\ +({ \ + holder.nr = info->nr; \ + needed += holder.nr * rec_size; \ +}) + +#define holder_prep_needed(nr, rec_size) \ +({ \ + holder.nr = info->nr; \ + holder.rec_size = info->rec_size; \ + needed += holder.nr * holder.rec_size; \ +}) + +#define holder_set_ptr(field, nr, rec_size) \ +({ \ + holder.field = ptr_to_u64(ptr); \ + ptr += nr * rec_size; \ +}) + +static int prep_prog_info(struct bpf_prog_info *const info, enum dump_mode mode, + void **info_data, size_t *const info_data_sz) +{ + struct bpf_prog_info holder = {}; + size_t needed = 0; + void *ptr; + + if (mode == DUMP_JITED) + holder_prep_needed_rec_sz(jited_prog_len, 1); + else + holder_prep_needed_rec_sz(xlated_prog_len, 1); + + holder_prep_needed_rec_sz(nr_jited_ksyms, sizeof(__u64)); + holder_prep_needed_rec_sz(nr_jited_func_lens, sizeof(__u32)); + holder_prep_needed(nr_func_info, func_info_rec_size); + holder_prep_needed(nr_line_info, line_info_rec_size); + holder_prep_needed(nr_jited_line_info, jited_line_info_rec_size); + + if (needed > *info_data_sz) { + *info_data = realloc(*info_data, needed); + if (!*info_data) + return -1; + *info_data_sz = needed; + } + + ptr = *info_data; + + if (mode == DUMP_JITED) + holder_set_ptr(jited_prog_insns, holder.jited_prog_len, 1); + else + holder_set_ptr(xlated_prog_insns, holder.xlated_prog_len, 1); + + holder_set_ptr(jited_ksyms, holder.nr_jited_ksyms, sizeof(__u64)); + holder_set_ptr(jited_func_lens, holder.nr_jited_func_lens, sizeof(__u32)); + holder_set_ptr(func_info, holder.nr_func_info, holder.func_info_rec_size); + holder_set_ptr(line_info, holder.nr_line_info, holder.line_info_rec_size); + holder_set_ptr(jited_line_info, holder.nr_jited_line_info, + holder.jited_line_info_rec_size); + + *info = holder; + return 0; +} + +#undef holder_prep_needed +#undef holder_prep_needed_rec_sz +#undef holder_set_ptr + static void print_boot_time(__u64 nsecs, char *buf, unsigned int size) { struct timespec real_time_ts, boot_time_ts; @@ -791,16 +857,18 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode, static int do_dump(int argc, char **argv) { - struct bpf_prog_info_linear *info_linear; + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); + size_t info_data_sz = 0; + void *info_data = NULL; char *filepath = NULL; bool opcodes = false; bool visual = false; enum dump_mode mode; bool linum = false; - int *fds = NULL; int nb_fds, i = 0; + int *fds = NULL; int err = -1; - __u64 arrays; if (is_prefix(*argv, "jited")) { if (disasm_init()) @@ -860,46 +928,46 @@ static int do_dump(int argc, char **argv) goto exit_close; } - if (mode == DUMP_JITED) - arrays = 1UL << BPF_PROG_INFO_JITED_INSNS; - else - arrays = 1UL << BPF_PROG_INFO_XLATED_INSNS; - - arrays |= 1UL << BPF_PROG_INFO_JITED_KSYMS; - arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS; - arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO; - arrays |= 1UL << BPF_PROG_INFO_LINE_INFO; - arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO; - if (json_output && nb_fds > 1) jsonw_start_array(json_wtr); /* root array */ for (i = 0; i < nb_fds; i++) { - info_linear = bpf_program__get_prog_info_linear(fds[i], arrays); - if (IS_ERR_OR_NULL(info_linear)) { + err = bpf_obj_get_info_by_fd(fds[i], &info, &info_len); + if (err) { + p_err("can't get prog info: %s", strerror(errno)); + break; + } + + err = prep_prog_info(&info, mode, &info_data, &info_data_sz); + if (err) { + p_err("can't grow prog info_data"); + break; + } + + err = bpf_obj_get_info_by_fd(fds[i], &info, &info_len); + if (err) { p_err("can't get prog info: %s", strerror(errno)); break; } if (json_output && nb_fds > 1) { jsonw_start_object(json_wtr); /* prog object */ - print_prog_header_json(&info_linear->info); + print_prog_header_json(&info); jsonw_name(json_wtr, "insns"); } else if (nb_fds > 1) { - print_prog_header_plain(&info_linear->info); + print_prog_header_plain(&info); } - err = prog_dump(&info_linear->info, mode, filepath, opcodes, - visual, linum); + err = prog_dump(&info, mode, filepath, opcodes, visual, linum); if (json_output && nb_fds > 1) jsonw_end_object(json_wtr); /* prog object */ else if (i != nb_fds - 1 && nb_fds > 1) printf("\n"); - free(info_linear); if (err) break; close(fds[i]); + memset(&info, 0, sizeof(info)); } if (json_output && nb_fds > 1) jsonw_end_array(json_wtr); /* root array */ @@ -908,6 +976,7 @@ static int do_dump(int argc, char **argv) for (; i < nb_fds; i++) close(fds[i]); exit_free: + free(info_data); free(fds); return err; } @@ -2004,41 +2073,58 @@ static void profile_print_readings(void) static char *profile_target_name(int tgt_fd) { - struct bpf_prog_info_linear *info_linear; - struct bpf_func_info *func_info; + struct bpf_func_info func_info; + struct bpf_prog_info info = {}; + __u32 info_len = sizeof(info); const struct btf_type *t; + __u32 func_info_rec_size; struct btf *btf = NULL; char *name = NULL; + int err; - info_linear = bpf_program__get_prog_info_linear( - tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO); - if (IS_ERR_OR_NULL(info_linear)) { - p_err("failed to get info_linear for prog FD %d", tgt_fd); - return NULL; + err = bpf_obj_get_info_by_fd(tgt_fd, &info, &info_len); + if (err) { + p_err("failed to bpf_obj_get_info_by_fd for prog FD %d", tgt_fd); + goto out; } - if (info_linear->info.btf_id == 0) { + if (info.btf_id == 0) { p_err("prog FD %d doesn't have valid btf", tgt_fd); goto out; } - btf = btf__load_from_kernel_by_id(info_linear->info.btf_id); + func_info_rec_size = info.func_info_rec_size; + if (info.nr_func_info == 0) { + p_err("bpf_obj_get_info_by_fd for prog FD %d found 0 func_info", tgt_fd); + goto out; + } + + memset(&info, 0, sizeof(info)); + info.nr_func_info = 1; + info.func_info_rec_size = func_info_rec_size; + info.func_info = ptr_to_u64(&func_info); + + err = bpf_obj_get_info_by_fd(tgt_fd, &info, &info_len); + if (err) { + p_err("failed to get func_info for prog FD %d", tgt_fd); + goto out; + } + + btf = btf__load_from_kernel_by_id(info.btf_id); if (libbpf_get_error(btf)) { p_err("failed to load btf for prog FD %d", tgt_fd); goto out; } - func_info = u64_to_ptr(info_linear->info.func_info); - t = btf__type_by_id(btf, func_info[0].type_id); + t = btf__type_by_id(btf, func_info.type_id); if (!t) { p_err("btf %d doesn't have type %d", - info_linear->info.btf_id, func_info[0].type_id); + info.btf_id, func_info.type_id); goto out; } name = strdup(btf__name_by_offset(btf, t->name_off)); out: btf__free(btf); - free(info_linear); return name; } -- 2.30.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly 2021-10-11 8:20 ` [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly Dave Marchevsky @ 2021-10-20 17:37 ` Andrii Nakryiko 2021-10-20 22:15 ` Quentin Monnet 0 siblings, 1 reply; 13+ messages in thread From: Andrii Nakryiko @ 2021-10-20 17:37 UTC (permalink / raw) To: Dave Marchevsky Cc: bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar, Quentin Monnet On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > > To prepare for impending deprecation of libbpf's > bpf_program__get_prog_info_linear, migrate uses of this function to use > bpf_obj_get_info_by_fd. > > Since the profile_target_name and dump_prog_id_as_func_ptr helpers were > only looking at the first func_info, avoid grabbing the rest to save a > malloc. For do_dump, add a more full-featured helper, but avoid > free/realloc of buffer when possible for multi-prog dumps. > > Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > --- > tools/bpf/bpftool/btf_dumper.c | 40 +++++---- > tools/bpf/bpftool/prog.c | 154 +++++++++++++++++++++++++-------- > 2 files changed, 144 insertions(+), 50 deletions(-) > > diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c > index 9c25286a5c73..0f85704628bf 100644 > --- a/tools/bpf/bpftool/btf_dumper.c > +++ b/tools/bpf/bpftool/btf_dumper.c > @@ -32,14 +32,16 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, > const struct btf_type *func_proto, > __u32 prog_id) > { > - struct bpf_prog_info_linear *prog_info = NULL; > const struct btf_type *func_type; > + int prog_fd = -1, func_sig_len; > + struct bpf_prog_info info = {}; > + __u32 info_len = sizeof(info); > const char *prog_name = NULL; > - struct bpf_func_info *finfo; > struct btf *prog_btf = NULL; > - struct bpf_prog_info *info; > - int prog_fd, func_sig_len; > + struct bpf_func_info finfo; > + __u32 finfo_rec_size; > char prog_str[1024]; > + int err; > > /* Get the ptr's func_proto */ > func_sig_len = btf_dump_func(d->btf, prog_str, func_proto, NULL, 0, > @@ -55,22 +57,27 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, > if (prog_fd == -1) please change this to (prog_fd < 0), see [0] for why we should check all the other places in bpftool to see if there are any patterns like this that would break on libbpf 1.0 (cc Quentin as well) [0] https://github.com/libbpf/libbpf/wiki/Libbpf-1.0-migration-guide#direct-error-code-returning-libbpf_strict_direct_errs > goto print; > > - prog_info = bpf_program__get_prog_info_linear(prog_fd, > - 1UL << BPF_PROG_INFO_FUNC_INFO); > - close(prog_fd); > - if (IS_ERR(prog_info)) { > - prog_info = NULL; > + err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); > + if (err) > goto print; > - } > - info = &prog_info->info; > > - if (!info->btf_id || !info->nr_func_info) > + if (!info.btf_id || !info.nr_func_info) > + goto print; > + > + finfo_rec_size = info.func_info_rec_size; > + memset(&info, 0, sizeof(info)); > + info.nr_func_info = 1; > + info.func_info_rec_size = finfo_rec_size; > + info.func_info = ptr_to_u64(&finfo); > + > + err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); > + if (err) > goto print; > - prog_btf = btf__load_from_kernel_by_id(info->btf_id); > + > + prog_btf = btf__load_from_kernel_by_id(info.btf_id); > if (libbpf_get_error(prog_btf)) > goto print; > - finfo = u64_to_ptr(info->func_info); > - func_type = btf__type_by_id(prog_btf, finfo->type_id); > + func_type = btf__type_by_id(prog_btf, finfo.type_id); > if (!func_type || !btf_is_func(func_type)) > goto print; > > @@ -92,7 +99,8 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, > prog_str[sizeof(prog_str) - 1] = '\0'; > jsonw_string(d->jw, prog_str); > btf__free(prog_btf); > - free(prog_info); > + if (prog_fd != -1) similarly, prog_fd >= 0 here; also, isn't this a fix? Can you add Fixes: tag then? > + close(prog_fd); > return 0; > } > > diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c > index a24ea7e26aa4..3b3ccc7b6dd4 100644 > --- a/tools/bpf/bpftool/prog.c > +++ b/tools/bpf/bpftool/prog.c > @@ -98,6 +98,72 @@ static enum bpf_attach_type parse_attach_type(const char *str) > return __MAX_BPF_ATTACH_TYPE; > } > > +#define holder_prep_needed_rec_sz(nr, rec_size)\ > +({ \ > + holder.nr = info->nr; \ > + needed += holder.nr * rec_size; \ > +}) > + > +#define holder_prep_needed(nr, rec_size) \ > +({ \ > + holder.nr = info->nr; \ > + holder.rec_size = info->rec_size; \ > + needed += holder.nr * holder.rec_size; \ > +}) > + > +#define holder_set_ptr(field, nr, rec_size) \ > +({ \ > + holder.field = ptr_to_u64(ptr); \ > + ptr += nr * rec_size; \ > +}) > + > +static int prep_prog_info(struct bpf_prog_info *const info, enum dump_mode mode, > + void **info_data, size_t *const info_data_sz) > +{ > + struct bpf_prog_info holder = {}; > + size_t needed = 0; > + void *ptr; > + > + if (mode == DUMP_JITED) > + holder_prep_needed_rec_sz(jited_prog_len, 1); > + else > + holder_prep_needed_rec_sz(xlated_prog_len, 1); > + > + holder_prep_needed_rec_sz(nr_jited_ksyms, sizeof(__u64)); > + holder_prep_needed_rec_sz(nr_jited_func_lens, sizeof(__u32)); > + holder_prep_needed(nr_func_info, func_info_rec_size); > + holder_prep_needed(nr_line_info, line_info_rec_size); > + holder_prep_needed(nr_jited_line_info, jited_line_info_rec_size); > + > + if (needed > *info_data_sz) { > + *info_data = realloc(*info_data, needed); never do `x = realloc(x);`, if realloc fails, original memory is leaked. Temporary variable is necessary to work with realloc, see a bunch of other places in libbpf where we use realloc for an example. > + if (!*info_data) > + return -1; > + *info_data_sz = needed; > + } > + > + ptr = *info_data; > + > + if (mode == DUMP_JITED) > + holder_set_ptr(jited_prog_insns, holder.jited_prog_len, 1); > + else > + holder_set_ptr(xlated_prog_insns, holder.xlated_prog_len, 1); > + > + holder_set_ptr(jited_ksyms, holder.nr_jited_ksyms, sizeof(__u64)); > + holder_set_ptr(jited_func_lens, holder.nr_jited_func_lens, sizeof(__u32)); > + holder_set_ptr(func_info, holder.nr_func_info, holder.func_info_rec_size); > + holder_set_ptr(line_info, holder.nr_line_info, holder.line_info_rec_size); > + holder_set_ptr(jited_line_info, holder.nr_jited_line_info, > + holder.jited_line_info_rec_size); tbh, I completely lost track of what these holder_xxx() macro actually do here... You saved few lines of code, but I think we lost a lot in readability > + > + *info = holder; instead of copying at the end, why not fill out the passed in bpf_prog_info directly? Of course *info stuff is annoying, but that's solved with a temporary variable, no? > + return 0; > +} > + > +#undef holder_prep_needed > +#undef holder_prep_needed_rec_sz > +#undef holder_set_ptr > + [...] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly 2021-10-20 17:37 ` Andrii Nakryiko @ 2021-10-20 22:15 ` Quentin Monnet 0 siblings, 0 replies; 13+ messages in thread From: Quentin Monnet @ 2021-10-20 22:15 UTC (permalink / raw) To: Andrii Nakryiko Cc: Dave Marchevsky, bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar On Wed, 20 Oct 2021 at 18:37, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > > > > To prepare for impending deprecation of libbpf's > > bpf_program__get_prog_info_linear, migrate uses of this function to use > > bpf_obj_get_info_by_fd. > > > > Since the profile_target_name and dump_prog_id_as_func_ptr helpers were > > only looking at the first func_info, avoid grabbing the rest to save a > > malloc. For do_dump, add a more full-featured helper, but avoid > > free/realloc of buffer when possible for multi-prog dumps. > > > > Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > > --- > > tools/bpf/bpftool/btf_dumper.c | 40 +++++---- > > tools/bpf/bpftool/prog.c | 154 +++++++++++++++++++++++++-------- > > 2 files changed, 144 insertions(+), 50 deletions(-) > > > > diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c > > index 9c25286a5c73..0f85704628bf 100644 > > --- a/tools/bpf/bpftool/btf_dumper.c > > +++ b/tools/bpf/bpftool/btf_dumper.c > > @@ -32,14 +32,16 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, > > const struct btf_type *func_proto, > > __u32 prog_id) > > { > > - struct bpf_prog_info_linear *prog_info = NULL; > > const struct btf_type *func_type; > > + int prog_fd = -1, func_sig_len; > > + struct bpf_prog_info info = {}; > > + __u32 info_len = sizeof(info); > > const char *prog_name = NULL; > > - struct bpf_func_info *finfo; > > struct btf *prog_btf = NULL; > > - struct bpf_prog_info *info; > > - int prog_fd, func_sig_len; > > + struct bpf_func_info finfo; > > + __u32 finfo_rec_size; > > char prog_str[1024]; > > + int err; > > > > /* Get the ptr's func_proto */ > > func_sig_len = btf_dump_func(d->btf, prog_str, func_proto, NULL, 0, > > @@ -55,22 +57,27 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d, > > if (prog_fd == -1) > > please change this to (prog_fd < 0), see [0] for why > > we should check all the other places in bpftool to see if there are > any patterns like this that would break on libbpf 1.0 (cc Quentin as > well) > > [0] https://github.com/libbpf/libbpf/wiki/Libbpf-1.0-migration-guide#direct-error-code-returning-libbpf_strict_direct_errs Hi! Looking at bpftool's code (looking for "-1"), I could find only two occurrences of that pattern, one in btf_dumper.c as noted above, and another one in struct_ops.c: fd = bpf_map_get_fd_by_id(id); if (fd == -1) { [...] } Dave, are you willing to address it as well? I can send a patch later this week otherwise. Thanks, Quentin ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear 2021-10-11 8:20 [PATCH v2 bpf-next 0/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-11 8:20 ` [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-11 8:20 ` [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly Dave Marchevsky @ 2021-10-11 8:20 ` Dave Marchevsky 2021-10-20 17:37 ` Andrii Nakryiko 2021-10-11 8:20 ` [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky 3 siblings, 1 reply; 13+ messages in thread From: Dave Marchevsky @ 2021-10-11 8:20 UTC (permalink / raw) To: bpf, linux-perf-users Cc: Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar, Dave Marchevsky To prepare for impending deprecation of libbpf's bpf_program__get_prog_info_linear, pull in the function and associated helpers into the perf codebase and migrate existing uses to the perf copy. Since libbpf's deprecated definitions will still be visible to perf, it is necessary to rename perf's definitions. Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> --- .../Documentation/perf.data-file-format.txt | 2 +- tools/perf/util/Build | 1 + tools/perf/util/annotate.c | 3 +- tools/perf/util/bpf-event.c | 41 ++- tools/perf/util/bpf-event.h | 2 +- tools/perf/util/bpf-utils.c | 261 ++++++++++++++++++ tools/perf/util/bpf-utils.h | 76 +++++ tools/perf/util/bpf_counter.c | 6 +- tools/perf/util/dso.c | 1 + tools/perf/util/env.c | 1 + tools/perf/util/header.c | 13 +- 11 files changed, 374 insertions(+), 33 deletions(-) create mode 100644 tools/perf/util/bpf-utils.c create mode 100644 tools/perf/util/bpf-utils.h diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index e6ff8c898ada..f56d0e0fbff6 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -346,7 +346,7 @@ to special needs. HEADER_BPF_PROG_INFO = 25, -struct bpf_prog_info_linear, which contains detailed information about +struct perf_bpil, which contains detailed information about a BPF program, including type, id, tag, jited/xlated instructions, etc. HEADER_BPF_BTF = 26, diff --git a/tools/perf/util/Build b/tools/perf/util/Build index f2914d5bed6e..ee42da1d3639 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -201,6 +201,7 @@ endif perf-y += perf-hooks.o perf-$(CONFIG_LIBBPF) += bpf-event.o +perf-$(CONFIG_LIBBPF) += bpf-utils.o perf-$(CONFIG_CXX) += c++/ diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 0bae061b2d6d..f0e5a236b7e3 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -28,6 +28,7 @@ #include "evsel.h" #include "evlist.h" #include "bpf-event.h" +#include "bpf-utils.h" #include "block-range.h" #include "string2.h" #include "util/event.h" @@ -1700,12 +1701,12 @@ static int symbol__disassemble_bpf(struct symbol *sym, { struct annotation *notes = symbol__annotation(sym); struct annotation_options *opts = args->options; - struct bpf_prog_info_linear *info_linear; struct bpf_prog_linfo *prog_linfo = NULL; struct bpf_prog_info_node *info_node; int len = sym->end - sym->start; disassembler_ftype disassemble; struct map *map = args->ms.map; + struct perf_bpil *info_linear; struct disassemble_info info; struct dso *dso = map->dso; int pc = 0, count, sub_id; diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 1a7112a87736..bac6dcf1fe81 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -10,6 +10,7 @@ #include <internal/lib.h> #include <symbol/kallsyms.h> #include "bpf-event.h" +#include "bpf-utils.h" #include "debug.h" #include "dso.h" #include "symbol.h" @@ -32,8 +33,6 @@ struct btf * __weak btf__load_from_kernel_by_id(__u32 id) return err ? ERR_PTR(err) : btf; } -#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) - static int snprintf_hex(char *buf, size_t size, unsigned char *data, size_t len) { int ret = 0; @@ -48,9 +47,9 @@ static int machine__process_bpf_event_load(struct machine *machine, union perf_event *event, struct perf_sample *sample __maybe_unused) { - struct bpf_prog_info_linear *info_linear; struct bpf_prog_info_node *info_node; struct perf_env *env = machine->env; + struct perf_bpil *info_linear; int id = event->bpf.id; unsigned int i; @@ -175,9 +174,9 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, { struct perf_record_ksymbol *ksymbol_event = &event->ksymbol; struct perf_record_bpf_event *bpf_event = &event->bpf; - struct bpf_prog_info_linear *info_linear; struct perf_tool *tool = session->tool; struct bpf_prog_info_node *info_node; + struct perf_bpil *info_linear; struct bpf_prog_info *info; struct btf *btf = NULL; struct perf_env *env; @@ -191,15 +190,15 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, */ env = session->data ? &session->header.env : &perf_env; - arrays = 1UL << BPF_PROG_INFO_JITED_KSYMS; - arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS; - arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO; - arrays |= 1UL << BPF_PROG_INFO_PROG_TAGS; - arrays |= 1UL << BPF_PROG_INFO_JITED_INSNS; - arrays |= 1UL << BPF_PROG_INFO_LINE_INFO; - arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO; + arrays = 1UL << PERF_BPIL_JITED_KSYMS; + arrays |= 1UL << PERF_BPIL_JITED_FUNC_LENS; + arrays |= 1UL << PERF_BPIL_FUNC_INFO; + arrays |= 1UL << PERF_BPIL_PROG_TAGS; + arrays |= 1UL << PERF_BPIL_JITED_INSNS; + arrays |= 1UL << PERF_BPIL_LINE_INFO; + arrays |= 1UL << PERF_BPIL_JITED_LINE_INFO; - info_linear = bpf_program__get_prog_info_linear(fd, arrays); + info_linear = get_bpf_prog_info_linear(fd, arrays); if (IS_ERR_OR_NULL(info_linear)) { info_linear = NULL; pr_debug("%s: failed to get BPF program info. aborting\n", __func__); @@ -452,8 +451,8 @@ int perf_event__synthesize_bpf_events(struct perf_session *session, static void perf_env__add_bpf_info(struct perf_env *env, u32 id) { - struct bpf_prog_info_linear *info_linear; struct bpf_prog_info_node *info_node; + struct perf_bpil *info_linear; struct btf *btf = NULL; u64 arrays; u32 btf_id; @@ -463,15 +462,15 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id) if (fd < 0) return; - arrays = 1UL << BPF_PROG_INFO_JITED_KSYMS; - arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS; - arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO; - arrays |= 1UL << BPF_PROG_INFO_PROG_TAGS; - arrays |= 1UL << BPF_PROG_INFO_JITED_INSNS; - arrays |= 1UL << BPF_PROG_INFO_LINE_INFO; - arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO; + arrays = 1UL << PERF_BPIL_JITED_KSYMS; + arrays |= 1UL << PERF_BPIL_JITED_FUNC_LENS; + arrays |= 1UL << PERF_BPIL_FUNC_INFO; + arrays |= 1UL << PERF_BPIL_PROG_TAGS; + arrays |= 1UL << PERF_BPIL_JITED_INSNS; + arrays |= 1UL << PERF_BPIL_LINE_INFO; + arrays |= 1UL << PERF_BPIL_JITED_LINE_INFO; - info_linear = bpf_program__get_prog_info_linear(fd, arrays); + info_linear = get_bpf_prog_info_linear(fd, arrays); if (IS_ERR_OR_NULL(info_linear)) { pr_debug("%s: failed to get BPF program info. aborting\n", __func__); goto out; diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h index 68f315c3df5b..144a8a24cc69 100644 --- a/tools/perf/util/bpf-event.h +++ b/tools/perf/util/bpf-event.h @@ -19,7 +19,7 @@ struct evlist; struct target; struct bpf_prog_info_node { - struct bpf_prog_info_linear *info_linear; + struct perf_bpil *info_linear; struct rb_node rb_node; }; diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c new file mode 100644 index 000000000000..e271e05e51bc --- /dev/null +++ b/tools/perf/util/bpf-utils.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <errno.h> +#include <stdlib.h> +#include <linux/err.h> +#include <linux/kernel.h> +#include <bpf/bpf.h> +#include "bpf-utils.h" +#include "debug.h" + +struct bpil_array_desc { + int array_offset; /* e.g. offset of jited_prog_insns */ + int count_offset; /* e.g. offset of jited_prog_len */ + int size_offset; /* > 0: offset of rec size, + * < 0: fix size of -size_offset + */ +}; + +static struct bpil_array_desc bpil_array_desc[] = { + [PERF_BPIL_JITED_INSNS] = { + offsetof(struct bpf_prog_info, jited_prog_insns), + offsetof(struct bpf_prog_info, jited_prog_len), + -1, + }, + [PERF_BPIL_XLATED_INSNS] = { + offsetof(struct bpf_prog_info, xlated_prog_insns), + offsetof(struct bpf_prog_info, xlated_prog_len), + -1, + }, + [PERF_BPIL_MAP_IDS] = { + offsetof(struct bpf_prog_info, map_ids), + offsetof(struct bpf_prog_info, nr_map_ids), + -(int)sizeof(__u32), + }, + [PERF_BPIL_JITED_KSYMS] = { + offsetof(struct bpf_prog_info, jited_ksyms), + offsetof(struct bpf_prog_info, nr_jited_ksyms), + -(int)sizeof(__u64), + }, + [PERF_BPIL_JITED_FUNC_LENS] = { + offsetof(struct bpf_prog_info, jited_func_lens), + offsetof(struct bpf_prog_info, nr_jited_func_lens), + -(int)sizeof(__u32), + }, + [PERF_BPIL_FUNC_INFO] = { + offsetof(struct bpf_prog_info, func_info), + offsetof(struct bpf_prog_info, nr_func_info), + offsetof(struct bpf_prog_info, func_info_rec_size), + }, + [PERF_BPIL_LINE_INFO] = { + offsetof(struct bpf_prog_info, line_info), + offsetof(struct bpf_prog_info, nr_line_info), + offsetof(struct bpf_prog_info, line_info_rec_size), + }, + [PERF_BPIL_JITED_LINE_INFO] = { + offsetof(struct bpf_prog_info, jited_line_info), + offsetof(struct bpf_prog_info, nr_jited_line_info), + offsetof(struct bpf_prog_info, jited_line_info_rec_size), + }, + [PERF_BPIL_PROG_TAGS] = { + offsetof(struct bpf_prog_info, prog_tags), + offsetof(struct bpf_prog_info, nr_prog_tags), + -(int)sizeof(__u8) * BPF_TAG_SIZE, + }, + +}; + +static __u32 bpf_prog_info_read_offset_u32(struct bpf_prog_info *info, + int offset) +{ + __u32 *array = (__u32 *)info; + + if (offset >= 0) + return array[offset / sizeof(__u32)]; + return -(int)offset; +} + +static __u64 bpf_prog_info_read_offset_u64(struct bpf_prog_info *info, + int offset) +{ + __u64 *array = (__u64 *)info; + + if (offset >= 0) + return array[offset / sizeof(__u64)]; + return -(int)offset; +} + +static void bpf_prog_info_set_offset_u32(struct bpf_prog_info *info, int offset, + __u32 val) +{ + __u32 *array = (__u32 *)info; + + if (offset >= 0) + array[offset / sizeof(__u32)] = val; +} + +static void bpf_prog_info_set_offset_u64(struct bpf_prog_info *info, int offset, + __u64 val) +{ + __u64 *array = (__u64 *)info; + + if (offset >= 0) + array[offset / sizeof(__u64)] = val; +} + +struct perf_bpil * +get_bpf_prog_info_linear(int fd, __u64 arrays) +{ + struct bpf_prog_info info = {}; + struct perf_bpil *info_linear; + __u32 info_len = sizeof(info); + __u32 data_len = 0; + int i, err; + void *ptr; + + if (arrays >> PERF_BPIL_LAST_ARRAY) + return ERR_PTR(-EINVAL); + + /* step 1: get array dimensions */ + err = bpf_obj_get_info_by_fd(fd, &info, &info_len); + if (err) { + pr_debug("can't get prog info: %s", strerror(errno)); + return ERR_PTR(-EFAULT); + } + + /* step 2: calculate total size of all arrays */ + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { + bool include_array = (arrays & (1UL << i)) > 0; + struct bpil_array_desc *desc; + __u32 count, size; + + desc = bpil_array_desc + i; + + /* kernel is too old to support this field */ + if (info_len < desc->array_offset + sizeof(__u32) || + info_len < desc->count_offset + sizeof(__u32) || + (desc->size_offset > 0 && info_len < (__u32)desc->size_offset)) + include_array = false; + + if (!include_array) { + arrays &= ~(1UL << i); /* clear the bit */ + continue; + } + + count = bpf_prog_info_read_offset_u32(&info, desc->count_offset); + size = bpf_prog_info_read_offset_u32(&info, desc->size_offset); + + data_len += count * size; + } + + /* step 3: allocate continuous memory */ + data_len = roundup(data_len, sizeof(__u64)); + info_linear = malloc(sizeof(struct perf_bpil) + data_len); + if (!info_linear) + return ERR_PTR(-ENOMEM); + + /* step 4: fill data to info_linear->info */ + info_linear->arrays = arrays; + memset(&info_linear->info, 0, sizeof(info)); + ptr = info_linear->data; + + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { + struct bpil_array_desc *desc; + __u32 count, size; + + if ((arrays & (1UL << i)) == 0) + continue; + + desc = bpil_array_desc + i; + count = bpf_prog_info_read_offset_u32(&info, desc->count_offset); + size = bpf_prog_info_read_offset_u32(&info, desc->size_offset); + bpf_prog_info_set_offset_u32(&info_linear->info, + desc->count_offset, count); + bpf_prog_info_set_offset_u32(&info_linear->info, + desc->size_offset, size); + bpf_prog_info_set_offset_u64(&info_linear->info, + desc->array_offset, + ptr_to_u64(ptr)); + ptr += count * size; + } + + /* step 5: call syscall again to get required arrays */ + err = bpf_obj_get_info_by_fd(fd, &info_linear->info, &info_len); + if (err) { + pr_debug("can't get prog info: %s", strerror(errno)); + free(info_linear); + return ERR_PTR(-EFAULT); + } + + /* step 6: verify the data */ + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { + struct bpil_array_desc *desc; + __u32 v1, v2; + + if ((arrays & (1UL << i)) == 0) + continue; + + desc = bpil_array_desc + i; + v1 = bpf_prog_info_read_offset_u32(&info, desc->count_offset); + v2 = bpf_prog_info_read_offset_u32(&info_linear->info, + desc->count_offset); + if (v1 != v2) + pr_warning("%s: mismatch in element count\n", __func__); + + v1 = bpf_prog_info_read_offset_u32(&info, desc->size_offset); + v2 = bpf_prog_info_read_offset_u32(&info_linear->info, + desc->size_offset); + if (v1 != v2) + pr_warning("%s: mismatch in rec size\n", __func__); + } + + /* step 7: update info_len and data_len */ + info_linear->info_len = sizeof(struct bpf_prog_info); + info_linear->data_len = data_len; + + return info_linear; +} + +void bpil_addr_to_offs(struct perf_bpil *info_linear) +{ + int i; + + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { + struct bpil_array_desc *desc; + __u64 addr, offs; + + if ((info_linear->arrays & (1UL << i)) == 0) + continue; + + desc = bpil_array_desc + i; + addr = bpf_prog_info_read_offset_u64(&info_linear->info, + desc->array_offset); + offs = addr - ptr_to_u64(info_linear->data); + bpf_prog_info_set_offset_u64(&info_linear->info, + desc->array_offset, offs); + } +} + +void bpil_offs_to_addr(struct perf_bpil *info_linear) +{ + int i; + + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { + struct bpil_array_desc *desc; + __u64 addr, offs; + + if ((info_linear->arrays & (1UL << i)) == 0) + continue; + + desc = bpil_array_desc + i; + offs = bpf_prog_info_read_offset_u64(&info_linear->info, + desc->array_offset); + addr = offs + ptr_to_u64(info_linear->data); + bpf_prog_info_set_offset_u64(&info_linear->info, + desc->array_offset, addr); + } +} diff --git a/tools/perf/util/bpf-utils.h b/tools/perf/util/bpf-utils.h new file mode 100644 index 000000000000..86a5055cdfad --- /dev/null +++ b/tools/perf/util/bpf-utils.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ + +#ifndef __PERF_BPF_UTILS_H +#define __PERF_BPF_UTILS_H + +#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) + +#ifdef HAVE_LIBBPF_SUPPORT + +#include <bpf/libbpf.h> + +/* + * Get bpf_prog_info in continuous memory + * + * struct bpf_prog_info has multiple arrays. The user has option to choose + * arrays to fetch from kernel. The following APIs provide an uniform way to + * fetch these data. All arrays in bpf_prog_info are stored in a single + * continuous memory region. This makes it easy to store the info in a + * file. + * + * Before writing perf_bpil to files, it is necessary to + * translate pointers in bpf_prog_info to offsets. Helper functions + * bpil_addr_to_offs() and bpil_offs_to_addr() + * are introduced to switch between pointers and offsets. + * + * Examples: + * # To fetch map_ids and prog_tags: + * __u64 arrays = (1UL << PERF_BPIL_MAP_IDS) | + * (1UL << PERF_BPIL_PROG_TAGS); + * struct perf_bpil *info_linear = + * get_bpf_prog_info_linear(fd, arrays); + * + * # To save data in file + * bpil_addr_to_offs(info_linear); + * write(f, info_linear, sizeof(*info_linear) + info_linear->data_len); + * + * # To read data from file + * read(f, info_linear, <proper_size>); + * bpil_offs_to_addr(info_linear); + */ +enum perf_bpil_array_types { + PERF_BPIL_FIRST_ARRAY = 0, + PERF_BPIL_JITED_INSNS = 0, + PERF_BPIL_XLATED_INSNS, + PERF_BPIL_MAP_IDS, + PERF_BPIL_JITED_KSYMS, + PERF_BPIL_JITED_FUNC_LENS, + PERF_BPIL_FUNC_INFO, + PERF_BPIL_LINE_INFO, + PERF_BPIL_JITED_LINE_INFO, + PERF_BPIL_PROG_TAGS, + PERF_BPIL_LAST_ARRAY, +}; + +struct perf_bpil { + /* size of struct bpf_prog_info, when the tool is compiled */ + __u32 info_len; + /* total bytes allocated for data, round up to 8 bytes */ + __u32 data_len; + /* which arrays are included in data */ + __u64 arrays; + struct bpf_prog_info info; + __u8 data[]; +}; + +struct perf_bpil * +get_bpf_prog_info_linear(int fd, __u64 arrays); + +void +bpil_addr_to_offs(struct perf_bpil *info_linear); + +void +bpil_offs_to_addr(struct perf_bpil *info_linear); + +#endif /* HAVE_LIBBPF_SUPPORT */ +#endif /* __PERF_BPF_UTILS_H */ diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c index ba0f20853651..2b04df8c5f87 100644 --- a/tools/perf/util/bpf_counter.c +++ b/tools/perf/util/bpf_counter.c @@ -13,6 +13,7 @@ #include <perf/bpf_perf.h> #include "bpf_counter.h" +#include "bpf-utils.h" #include "counts.h" #include "debug.h" #include "evsel.h" @@ -61,14 +62,13 @@ static int bpf_program_profiler__destroy(struct evsel *evsel) static char *bpf_target_prog_name(int tgt_fd) { - struct bpf_prog_info_linear *info_linear; struct bpf_func_info *func_info; + struct perf_bpil *info_linear; const struct btf_type *t; struct btf *btf = NULL; char *name = NULL; - info_linear = bpf_program__get_prog_info_linear( - tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO); + info_linear = get_bpf_prog_info_linear(tgt_fd, 1UL << PERF_BPIL_FUNC_INFO); if (IS_ERR_OR_NULL(info_linear)) { pr_debug("failed to get info_linear for prog FD %d\n", tgt_fd); return NULL; diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 9ed9a5676d35..9cc8a1772b4b 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -14,6 +14,7 @@ #ifdef HAVE_LIBBPF_SUPPORT #include <bpf/libbpf.h> #include "bpf-event.h" +#include "bpf-utils.h" #endif #include "compress.h" #include "env.h" diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index cf773f0dec38..17f1dd0680b4 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -16,6 +16,7 @@ struct perf_env perf_env; #ifdef HAVE_LIBBPF_SUPPORT #include "bpf-event.h" +#include "bpf-utils.h" #include <bpf/libbpf.h> void perf_env__insert_bpf_prog_info(struct perf_env *env, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 1c7414f66655..56511db8fa03 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -48,6 +48,7 @@ #include "util/util.h" // perf_exe() #include "cputopo.h" #include "bpf-event.h" +#include "bpf-utils.h" #include "clockid.h" #include "pmu-hybrid.h" @@ -1006,17 +1007,17 @@ static int write_bpf_prog_info(struct feat_fd *ff, node = rb_entry(next, struct bpf_prog_info_node, rb_node); next = rb_next(&node->rb_node); - len = sizeof(struct bpf_prog_info_linear) + + len = sizeof(struct perf_bpil) + node->info_linear->data_len; /* before writing to file, translate address to offset */ - bpf_program__bpil_addr_to_offs(node->info_linear); + bpil_addr_to_offs(node->info_linear); ret = do_write(ff, node->info_linear, len); /* * translate back to address even when do_write() fails, * so that this function never changes the data. */ - bpf_program__bpil_offs_to_addr(node->info_linear); + bpil_offs_to_addr(node->info_linear); if (ret < 0) goto out; } @@ -3018,9 +3019,9 @@ static int process_dir_format(struct feat_fd *ff, #ifdef HAVE_LIBBPF_SUPPORT static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) { - struct bpf_prog_info_linear *info_linear; struct bpf_prog_info_node *info_node; struct perf_env *env = &ff->ph->env; + struct perf_bpil *info_linear; u32 count, i; int err = -1; @@ -3049,7 +3050,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) goto out; } - info_linear = malloc(sizeof(struct bpf_prog_info_linear) + + info_linear = malloc(sizeof(struct perf_bpil) + data_len); if (!info_linear) goto out; @@ -3071,7 +3072,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) goto out; /* after reading from file, translate offset to address */ - bpf_program__bpil_offs_to_addr(info_linear); + bpil_offs_to_addr(info_linear); info_node->info_linear = info_linear; perf_env__insert_bpf_prog_info(env, info_node); } -- 2.30.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear 2021-10-11 8:20 ` [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear Dave Marchevsky @ 2021-10-20 17:37 ` Andrii Nakryiko [not found] ` <5080FF1F-8E7A-4AF7-AD7E-7349E58CFEDB@fb.com> 0 siblings, 1 reply; 13+ messages in thread From: Andrii Nakryiko @ 2021-10-20 17:37 UTC (permalink / raw) To: Dave Marchevsky Cc: bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > > To prepare for impending deprecation of libbpf's > bpf_program__get_prog_info_linear, pull in the function and associated > helpers into the perf codebase and migrate existing uses to the perf > copy. > > Since libbpf's deprecated definitions will still be visible to perf, it > is necessary to rename perf's definitions. > > Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > --- LGTM, but, Song, can you please take a look as well? > .../Documentation/perf.data-file-format.txt | 2 +- > tools/perf/util/Build | 1 + > tools/perf/util/annotate.c | 3 +- > tools/perf/util/bpf-event.c | 41 ++- > tools/perf/util/bpf-event.h | 2 +- > tools/perf/util/bpf-utils.c | 261 ++++++++++++++++++ > tools/perf/util/bpf-utils.h | 76 +++++ > tools/perf/util/bpf_counter.c | 6 +- > tools/perf/util/dso.c | 1 + > tools/perf/util/env.c | 1 + > tools/perf/util/header.c | 13 +- > 11 files changed, 374 insertions(+), 33 deletions(-) > create mode 100644 tools/perf/util/bpf-utils.c > create mode 100644 tools/perf/util/bpf-utils.h > > diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt > index e6ff8c898ada..f56d0e0fbff6 100644 > --- a/tools/perf/Documentation/perf.data-file-format.txt > +++ b/tools/perf/Documentation/perf.data-file-format.txt > @@ -346,7 +346,7 @@ to special needs. > > HEADER_BPF_PROG_INFO = 25, > > -struct bpf_prog_info_linear, which contains detailed information about > +struct perf_bpil, which contains detailed information about > a BPF program, including type, id, tag, jited/xlated instructions, etc. > > HEADER_BPF_BTF = 26, > diff --git a/tools/perf/util/Build b/tools/perf/util/Build > index f2914d5bed6e..ee42da1d3639 100644 > --- a/tools/perf/util/Build > +++ b/tools/perf/util/Build > @@ -201,6 +201,7 @@ endif > perf-y += perf-hooks.o > > perf-$(CONFIG_LIBBPF) += bpf-event.o > +perf-$(CONFIG_LIBBPF) += bpf-utils.o > > perf-$(CONFIG_CXX) += c++/ > > diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c > index 0bae061b2d6d..f0e5a236b7e3 100644 > --- a/tools/perf/util/annotate.c > +++ b/tools/perf/util/annotate.c > @@ -28,6 +28,7 @@ > #include "evsel.h" > #include "evlist.h" > #include "bpf-event.h" > +#include "bpf-utils.h" > #include "block-range.h" > #include "string2.h" > #include "util/event.h" > @@ -1700,12 +1701,12 @@ static int symbol__disassemble_bpf(struct symbol *sym, > { > struct annotation *notes = symbol__annotation(sym); > struct annotation_options *opts = args->options; > - struct bpf_prog_info_linear *info_linear; > struct bpf_prog_linfo *prog_linfo = NULL; > struct bpf_prog_info_node *info_node; > int len = sym->end - sym->start; > disassembler_ftype disassemble; > struct map *map = args->ms.map; > + struct perf_bpil *info_linear; > struct disassemble_info info; > struct dso *dso = map->dso; > int pc = 0, count, sub_id; > diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c > index 1a7112a87736..bac6dcf1fe81 100644 > --- a/tools/perf/util/bpf-event.c > +++ b/tools/perf/util/bpf-event.c > @@ -10,6 +10,7 @@ > #include <internal/lib.h> > #include <symbol/kallsyms.h> > #include "bpf-event.h" > +#include "bpf-utils.h" > #include "debug.h" > #include "dso.h" > #include "symbol.h" > @@ -32,8 +33,6 @@ struct btf * __weak btf__load_from_kernel_by_id(__u32 id) > return err ? ERR_PTR(err) : btf; > } > > -#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) > - > static int snprintf_hex(char *buf, size_t size, unsigned char *data, size_t len) > { > int ret = 0; > @@ -48,9 +47,9 @@ static int machine__process_bpf_event_load(struct machine *machine, > union perf_event *event, > struct perf_sample *sample __maybe_unused) > { > - struct bpf_prog_info_linear *info_linear; > struct bpf_prog_info_node *info_node; > struct perf_env *env = machine->env; > + struct perf_bpil *info_linear; > int id = event->bpf.id; > unsigned int i; > > @@ -175,9 +174,9 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, > { > struct perf_record_ksymbol *ksymbol_event = &event->ksymbol; > struct perf_record_bpf_event *bpf_event = &event->bpf; > - struct bpf_prog_info_linear *info_linear; > struct perf_tool *tool = session->tool; > struct bpf_prog_info_node *info_node; > + struct perf_bpil *info_linear; > struct bpf_prog_info *info; > struct btf *btf = NULL; > struct perf_env *env; > @@ -191,15 +190,15 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session, > */ > env = session->data ? &session->header.env : &perf_env; > > - arrays = 1UL << BPF_PROG_INFO_JITED_KSYMS; > - arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS; > - arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO; > - arrays |= 1UL << BPF_PROG_INFO_PROG_TAGS; > - arrays |= 1UL << BPF_PROG_INFO_JITED_INSNS; > - arrays |= 1UL << BPF_PROG_INFO_LINE_INFO; > - arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO; > + arrays = 1UL << PERF_BPIL_JITED_KSYMS; > + arrays |= 1UL << PERF_BPIL_JITED_FUNC_LENS; > + arrays |= 1UL << PERF_BPIL_FUNC_INFO; > + arrays |= 1UL << PERF_BPIL_PROG_TAGS; > + arrays |= 1UL << PERF_BPIL_JITED_INSNS; > + arrays |= 1UL << PERF_BPIL_LINE_INFO; > + arrays |= 1UL << PERF_BPIL_JITED_LINE_INFO; > > - info_linear = bpf_program__get_prog_info_linear(fd, arrays); > + info_linear = get_bpf_prog_info_linear(fd, arrays); > if (IS_ERR_OR_NULL(info_linear)) { > info_linear = NULL; > pr_debug("%s: failed to get BPF program info. aborting\n", __func__); > @@ -452,8 +451,8 @@ int perf_event__synthesize_bpf_events(struct perf_session *session, > > static void perf_env__add_bpf_info(struct perf_env *env, u32 id) > { > - struct bpf_prog_info_linear *info_linear; > struct bpf_prog_info_node *info_node; > + struct perf_bpil *info_linear; > struct btf *btf = NULL; > u64 arrays; > u32 btf_id; > @@ -463,15 +462,15 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id) > if (fd < 0) > return; > > - arrays = 1UL << BPF_PROG_INFO_JITED_KSYMS; > - arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS; > - arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO; > - arrays |= 1UL << BPF_PROG_INFO_PROG_TAGS; > - arrays |= 1UL << BPF_PROG_INFO_JITED_INSNS; > - arrays |= 1UL << BPF_PROG_INFO_LINE_INFO; > - arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO; > + arrays = 1UL << PERF_BPIL_JITED_KSYMS; > + arrays |= 1UL << PERF_BPIL_JITED_FUNC_LENS; > + arrays |= 1UL << PERF_BPIL_FUNC_INFO; > + arrays |= 1UL << PERF_BPIL_PROG_TAGS; > + arrays |= 1UL << PERF_BPIL_JITED_INSNS; > + arrays |= 1UL << PERF_BPIL_LINE_INFO; > + arrays |= 1UL << PERF_BPIL_JITED_LINE_INFO; > > - info_linear = bpf_program__get_prog_info_linear(fd, arrays); > + info_linear = get_bpf_prog_info_linear(fd, arrays); > if (IS_ERR_OR_NULL(info_linear)) { > pr_debug("%s: failed to get BPF program info. aborting\n", __func__); > goto out; > diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h > index 68f315c3df5b..144a8a24cc69 100644 > --- a/tools/perf/util/bpf-event.h > +++ b/tools/perf/util/bpf-event.h > @@ -19,7 +19,7 @@ struct evlist; > struct target; > > struct bpf_prog_info_node { > - struct bpf_prog_info_linear *info_linear; > + struct perf_bpil *info_linear; > struct rb_node rb_node; > }; > > diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c > new file mode 100644 > index 000000000000..e271e05e51bc > --- /dev/null > +++ b/tools/perf/util/bpf-utils.c > @@ -0,0 +1,261 @@ > +// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#endif > + > +#include <errno.h> > +#include <stdlib.h> > +#include <linux/err.h> > +#include <linux/kernel.h> > +#include <bpf/bpf.h> > +#include "bpf-utils.h" > +#include "debug.h" > + > +struct bpil_array_desc { > + int array_offset; /* e.g. offset of jited_prog_insns */ > + int count_offset; /* e.g. offset of jited_prog_len */ > + int size_offset; /* > 0: offset of rec size, > + * < 0: fix size of -size_offset > + */ > +}; > + > +static struct bpil_array_desc bpil_array_desc[] = { > + [PERF_BPIL_JITED_INSNS] = { > + offsetof(struct bpf_prog_info, jited_prog_insns), > + offsetof(struct bpf_prog_info, jited_prog_len), > + -1, > + }, > + [PERF_BPIL_XLATED_INSNS] = { > + offsetof(struct bpf_prog_info, xlated_prog_insns), > + offsetof(struct bpf_prog_info, xlated_prog_len), > + -1, > + }, > + [PERF_BPIL_MAP_IDS] = { > + offsetof(struct bpf_prog_info, map_ids), > + offsetof(struct bpf_prog_info, nr_map_ids), > + -(int)sizeof(__u32), > + }, > + [PERF_BPIL_JITED_KSYMS] = { > + offsetof(struct bpf_prog_info, jited_ksyms), > + offsetof(struct bpf_prog_info, nr_jited_ksyms), > + -(int)sizeof(__u64), > + }, > + [PERF_BPIL_JITED_FUNC_LENS] = { > + offsetof(struct bpf_prog_info, jited_func_lens), > + offsetof(struct bpf_prog_info, nr_jited_func_lens), > + -(int)sizeof(__u32), > + }, > + [PERF_BPIL_FUNC_INFO] = { > + offsetof(struct bpf_prog_info, func_info), > + offsetof(struct bpf_prog_info, nr_func_info), > + offsetof(struct bpf_prog_info, func_info_rec_size), > + }, > + [PERF_BPIL_LINE_INFO] = { > + offsetof(struct bpf_prog_info, line_info), > + offsetof(struct bpf_prog_info, nr_line_info), > + offsetof(struct bpf_prog_info, line_info_rec_size), > + }, > + [PERF_BPIL_JITED_LINE_INFO] = { > + offsetof(struct bpf_prog_info, jited_line_info), > + offsetof(struct bpf_prog_info, nr_jited_line_info), > + offsetof(struct bpf_prog_info, jited_line_info_rec_size), > + }, > + [PERF_BPIL_PROG_TAGS] = { > + offsetof(struct bpf_prog_info, prog_tags), > + offsetof(struct bpf_prog_info, nr_prog_tags), > + -(int)sizeof(__u8) * BPF_TAG_SIZE, > + }, > + > +}; > + > +static __u32 bpf_prog_info_read_offset_u32(struct bpf_prog_info *info, > + int offset) > +{ > + __u32 *array = (__u32 *)info; > + > + if (offset >= 0) > + return array[offset / sizeof(__u32)]; > + return -(int)offset; > +} > + > +static __u64 bpf_prog_info_read_offset_u64(struct bpf_prog_info *info, > + int offset) > +{ > + __u64 *array = (__u64 *)info; > + > + if (offset >= 0) > + return array[offset / sizeof(__u64)]; > + return -(int)offset; > +} > + > +static void bpf_prog_info_set_offset_u32(struct bpf_prog_info *info, int offset, > + __u32 val) > +{ > + __u32 *array = (__u32 *)info; > + > + if (offset >= 0) > + array[offset / sizeof(__u32)] = val; > +} > + > +static void bpf_prog_info_set_offset_u64(struct bpf_prog_info *info, int offset, > + __u64 val) > +{ > + __u64 *array = (__u64 *)info; > + > + if (offset >= 0) > + array[offset / sizeof(__u64)] = val; > +} > + > +struct perf_bpil * > +get_bpf_prog_info_linear(int fd, __u64 arrays) > +{ > + struct bpf_prog_info info = {}; > + struct perf_bpil *info_linear; > + __u32 info_len = sizeof(info); > + __u32 data_len = 0; > + int i, err; > + void *ptr; > + > + if (arrays >> PERF_BPIL_LAST_ARRAY) > + return ERR_PTR(-EINVAL); > + > + /* step 1: get array dimensions */ > + err = bpf_obj_get_info_by_fd(fd, &info, &info_len); > + if (err) { > + pr_debug("can't get prog info: %s", strerror(errno)); > + return ERR_PTR(-EFAULT); > + } > + > + /* step 2: calculate total size of all arrays */ > + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { > + bool include_array = (arrays & (1UL << i)) > 0; > + struct bpil_array_desc *desc; > + __u32 count, size; > + > + desc = bpil_array_desc + i; > + > + /* kernel is too old to support this field */ > + if (info_len < desc->array_offset + sizeof(__u32) || > + info_len < desc->count_offset + sizeof(__u32) || > + (desc->size_offset > 0 && info_len < (__u32)desc->size_offset)) > + include_array = false; > + > + if (!include_array) { > + arrays &= ~(1UL << i); /* clear the bit */ > + continue; > + } > + > + count = bpf_prog_info_read_offset_u32(&info, desc->count_offset); > + size = bpf_prog_info_read_offset_u32(&info, desc->size_offset); > + > + data_len += count * size; > + } > + > + /* step 3: allocate continuous memory */ > + data_len = roundup(data_len, sizeof(__u64)); > + info_linear = malloc(sizeof(struct perf_bpil) + data_len); > + if (!info_linear) > + return ERR_PTR(-ENOMEM); > + > + /* step 4: fill data to info_linear->info */ > + info_linear->arrays = arrays; > + memset(&info_linear->info, 0, sizeof(info)); > + ptr = info_linear->data; > + > + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { > + struct bpil_array_desc *desc; > + __u32 count, size; > + > + if ((arrays & (1UL << i)) == 0) > + continue; > + > + desc = bpil_array_desc + i; > + count = bpf_prog_info_read_offset_u32(&info, desc->count_offset); > + size = bpf_prog_info_read_offset_u32(&info, desc->size_offset); > + bpf_prog_info_set_offset_u32(&info_linear->info, > + desc->count_offset, count); > + bpf_prog_info_set_offset_u32(&info_linear->info, > + desc->size_offset, size); > + bpf_prog_info_set_offset_u64(&info_linear->info, > + desc->array_offset, > + ptr_to_u64(ptr)); > + ptr += count * size; > + } > + > + /* step 5: call syscall again to get required arrays */ > + err = bpf_obj_get_info_by_fd(fd, &info_linear->info, &info_len); > + if (err) { > + pr_debug("can't get prog info: %s", strerror(errno)); > + free(info_linear); > + return ERR_PTR(-EFAULT); > + } > + > + /* step 6: verify the data */ > + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { > + struct bpil_array_desc *desc; > + __u32 v1, v2; > + > + if ((arrays & (1UL << i)) == 0) > + continue; > + > + desc = bpil_array_desc + i; > + v1 = bpf_prog_info_read_offset_u32(&info, desc->count_offset); > + v2 = bpf_prog_info_read_offset_u32(&info_linear->info, > + desc->count_offset); > + if (v1 != v2) > + pr_warning("%s: mismatch in element count\n", __func__); > + > + v1 = bpf_prog_info_read_offset_u32(&info, desc->size_offset); > + v2 = bpf_prog_info_read_offset_u32(&info_linear->info, > + desc->size_offset); > + if (v1 != v2) > + pr_warning("%s: mismatch in rec size\n", __func__); > + } > + > + /* step 7: update info_len and data_len */ > + info_linear->info_len = sizeof(struct bpf_prog_info); > + info_linear->data_len = data_len; > + > + return info_linear; > +} > + > +void bpil_addr_to_offs(struct perf_bpil *info_linear) > +{ > + int i; > + > + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { > + struct bpil_array_desc *desc; > + __u64 addr, offs; > + > + if ((info_linear->arrays & (1UL << i)) == 0) > + continue; > + > + desc = bpil_array_desc + i; > + addr = bpf_prog_info_read_offset_u64(&info_linear->info, > + desc->array_offset); > + offs = addr - ptr_to_u64(info_linear->data); > + bpf_prog_info_set_offset_u64(&info_linear->info, > + desc->array_offset, offs); > + } > +} > + > +void bpil_offs_to_addr(struct perf_bpil *info_linear) > +{ > + int i; > + > + for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { > + struct bpil_array_desc *desc; > + __u64 addr, offs; > + > + if ((info_linear->arrays & (1UL << i)) == 0) > + continue; > + > + desc = bpil_array_desc + i; > + offs = bpf_prog_info_read_offset_u64(&info_linear->info, > + desc->array_offset); > + addr = offs + ptr_to_u64(info_linear->data); > + bpf_prog_info_set_offset_u64(&info_linear->info, > + desc->array_offset, addr); > + } > +} > diff --git a/tools/perf/util/bpf-utils.h b/tools/perf/util/bpf-utils.h > new file mode 100644 > index 000000000000..86a5055cdfad > --- /dev/null > +++ b/tools/perf/util/bpf-utils.h > @@ -0,0 +1,76 @@ > +/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ > + > +#ifndef __PERF_BPF_UTILS_H > +#define __PERF_BPF_UTILS_H > + > +#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr)) > + > +#ifdef HAVE_LIBBPF_SUPPORT > + > +#include <bpf/libbpf.h> > + > +/* > + * Get bpf_prog_info in continuous memory > + * > + * struct bpf_prog_info has multiple arrays. The user has option to choose > + * arrays to fetch from kernel. The following APIs provide an uniform way to > + * fetch these data. All arrays in bpf_prog_info are stored in a single > + * continuous memory region. This makes it easy to store the info in a > + * file. > + * > + * Before writing perf_bpil to files, it is necessary to > + * translate pointers in bpf_prog_info to offsets. Helper functions > + * bpil_addr_to_offs() and bpil_offs_to_addr() > + * are introduced to switch between pointers and offsets. > + * > + * Examples: > + * # To fetch map_ids and prog_tags: > + * __u64 arrays = (1UL << PERF_BPIL_MAP_IDS) | > + * (1UL << PERF_BPIL_PROG_TAGS); > + * struct perf_bpil *info_linear = > + * get_bpf_prog_info_linear(fd, arrays); > + * > + * # To save data in file > + * bpil_addr_to_offs(info_linear); > + * write(f, info_linear, sizeof(*info_linear) + info_linear->data_len); > + * > + * # To read data from file > + * read(f, info_linear, <proper_size>); > + * bpil_offs_to_addr(info_linear); > + */ > +enum perf_bpil_array_types { > + PERF_BPIL_FIRST_ARRAY = 0, > + PERF_BPIL_JITED_INSNS = 0, > + PERF_BPIL_XLATED_INSNS, > + PERF_BPIL_MAP_IDS, > + PERF_BPIL_JITED_KSYMS, > + PERF_BPIL_JITED_FUNC_LENS, > + PERF_BPIL_FUNC_INFO, > + PERF_BPIL_LINE_INFO, > + PERF_BPIL_JITED_LINE_INFO, > + PERF_BPIL_PROG_TAGS, > + PERF_BPIL_LAST_ARRAY, > +}; > + > +struct perf_bpil { > + /* size of struct bpf_prog_info, when the tool is compiled */ > + __u32 info_len; > + /* total bytes allocated for data, round up to 8 bytes */ > + __u32 data_len; > + /* which arrays are included in data */ > + __u64 arrays; > + struct bpf_prog_info info; > + __u8 data[]; > +}; > + > +struct perf_bpil * > +get_bpf_prog_info_linear(int fd, __u64 arrays); > + > +void > +bpil_addr_to_offs(struct perf_bpil *info_linear); > + > +void > +bpil_offs_to_addr(struct perf_bpil *info_linear); > + > +#endif /* HAVE_LIBBPF_SUPPORT */ > +#endif /* __PERF_BPF_UTILS_H */ > diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c > index ba0f20853651..2b04df8c5f87 100644 > --- a/tools/perf/util/bpf_counter.c > +++ b/tools/perf/util/bpf_counter.c > @@ -13,6 +13,7 @@ > #include <perf/bpf_perf.h> > > #include "bpf_counter.h" > +#include "bpf-utils.h" > #include "counts.h" > #include "debug.h" > #include "evsel.h" > @@ -61,14 +62,13 @@ static int bpf_program_profiler__destroy(struct evsel *evsel) > > static char *bpf_target_prog_name(int tgt_fd) > { > - struct bpf_prog_info_linear *info_linear; > struct bpf_func_info *func_info; > + struct perf_bpil *info_linear; > const struct btf_type *t; > struct btf *btf = NULL; > char *name = NULL; > > - info_linear = bpf_program__get_prog_info_linear( > - tgt_fd, 1UL << BPF_PROG_INFO_FUNC_INFO); > + info_linear = get_bpf_prog_info_linear(tgt_fd, 1UL << PERF_BPIL_FUNC_INFO); > if (IS_ERR_OR_NULL(info_linear)) { > pr_debug("failed to get info_linear for prog FD %d\n", tgt_fd); > return NULL; > diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c > index 9ed9a5676d35..9cc8a1772b4b 100644 > --- a/tools/perf/util/dso.c > +++ b/tools/perf/util/dso.c > @@ -14,6 +14,7 @@ > #ifdef HAVE_LIBBPF_SUPPORT > #include <bpf/libbpf.h> > #include "bpf-event.h" > +#include "bpf-utils.h" > #endif > #include "compress.h" > #include "env.h" > diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c > index cf773f0dec38..17f1dd0680b4 100644 > --- a/tools/perf/util/env.c > +++ b/tools/perf/util/env.c > @@ -16,6 +16,7 @@ struct perf_env perf_env; > > #ifdef HAVE_LIBBPF_SUPPORT > #include "bpf-event.h" > +#include "bpf-utils.h" > #include <bpf/libbpf.h> > > void perf_env__insert_bpf_prog_info(struct perf_env *env, > diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c > index 1c7414f66655..56511db8fa03 100644 > --- a/tools/perf/util/header.c > +++ b/tools/perf/util/header.c > @@ -48,6 +48,7 @@ > #include "util/util.h" // perf_exe() > #include "cputopo.h" > #include "bpf-event.h" > +#include "bpf-utils.h" > #include "clockid.h" > #include "pmu-hybrid.h" > > @@ -1006,17 +1007,17 @@ static int write_bpf_prog_info(struct feat_fd *ff, > > node = rb_entry(next, struct bpf_prog_info_node, rb_node); > next = rb_next(&node->rb_node); > - len = sizeof(struct bpf_prog_info_linear) + > + len = sizeof(struct perf_bpil) + > node->info_linear->data_len; > > /* before writing to file, translate address to offset */ > - bpf_program__bpil_addr_to_offs(node->info_linear); > + bpil_addr_to_offs(node->info_linear); > ret = do_write(ff, node->info_linear, len); > /* > * translate back to address even when do_write() fails, > * so that this function never changes the data. > */ > - bpf_program__bpil_offs_to_addr(node->info_linear); > + bpil_offs_to_addr(node->info_linear); > if (ret < 0) > goto out; > } > @@ -3018,9 +3019,9 @@ static int process_dir_format(struct feat_fd *ff, > #ifdef HAVE_LIBBPF_SUPPORT > static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) > { > - struct bpf_prog_info_linear *info_linear; > struct bpf_prog_info_node *info_node; > struct perf_env *env = &ff->ph->env; > + struct perf_bpil *info_linear; > u32 count, i; > int err = -1; > > @@ -3049,7 +3050,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) > goto out; > } > > - info_linear = malloc(sizeof(struct bpf_prog_info_linear) + > + info_linear = malloc(sizeof(struct perf_bpil) + > data_len); > if (!info_linear) > goto out; > @@ -3071,7 +3072,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused) > goto out; > > /* after reading from file, translate offset to address */ > - bpf_program__bpil_offs_to_addr(info_linear); > + bpil_offs_to_addr(info_linear); > info_node->info_linear = info_linear; > perf_env__insert_bpf_prog_info(env, info_node); > } > -- > 2.30.2 > ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <5080FF1F-8E7A-4AF7-AD7E-7349E58CFEDB@fb.com>]
* Re: [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear [not found] ` <5080FF1F-8E7A-4AF7-AD7E-7349E58CFEDB@fb.com> @ 2021-10-31 17:13 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 13+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-10-31 17:13 UTC (permalink / raw) To: Song Liu Cc: Andrii Nakryiko, Arnaldo Carvalho de Melo, Dave Marchevsky, bpf, linux-perf-use., Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Peter Zijlstra, Ingo Molnar Em Thu, Oct 28, 2021 at 08:44:51PM +0000, Song Liu escreveu: > > > > On Oct 20, 2021, at 10:37 AM, Andrii Nakryiko <andrii.nakryiko@gmail.com> wrote: > > > > On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > >> > >> To prepare for impending deprecation of libbpf's > >> bpf_program__get_prog_info_linear, pull in the function and associated > >> helpers into the perf codebase and migrate existing uses to the perf > >> copy. > >> > >> Since libbpf's deprecated definitions will still be visible to perf, it > >> is necessary to rename perf's definitions. > >> > >> Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > >> --- > > > > LGTM, but, Song, can you please take a look as well? > > Sorry for the delay. > > Acked-by: Song Liu <songliubraving@fb.com> > > Also cc'ing Arnaldo's other email. Thanks, I'll get to this. - Arnaldo ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear 2021-10-11 8:20 [PATCH v2 bpf-next 0/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky ` (2 preceding siblings ...) 2021-10-11 8:20 ` [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear Dave Marchevsky @ 2021-10-11 8:20 ` Dave Marchevsky 2021-10-20 17:37 ` Andrii Nakryiko 3 siblings, 1 reply; 13+ messages in thread From: Dave Marchevsky @ 2021-10-11 8:20 UTC (permalink / raw) To: bpf, linux-perf-users Cc: Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar, Dave Marchevsky As part of the road to libbpf 1.0, and discussed in libbpf issue tracker [0], bpf_program__get_prog_info_linear and its associated structs and helper functions should be deprecated. The functionality is too specific to the needs of 'perf', and there's little/no out-of-tree usage to preclude introduction of a more general helper in the future. [0] Closes: https://github.com/libbpf/libbpf/issues/313 Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> --- tools/lib/bpf/libbpf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 89ca9c83ed4e..285008b46e1b 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -877,12 +877,15 @@ struct bpf_prog_info_linear { __u8 data[]; }; +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") LIBBPF_API struct bpf_prog_info_linear * bpf_program__get_prog_info_linear(int fd, __u64 arrays); +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") LIBBPF_API void bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear); +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") LIBBPF_API void bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear); -- 2.30.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear 2021-10-11 8:20 ` [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky @ 2021-10-20 17:37 ` Andrii Nakryiko 2021-10-20 21:01 ` Toke Høiland-Jørgensen 0 siblings, 1 reply; 13+ messages in thread From: Andrii Nakryiko @ 2021-10-20 17:37 UTC (permalink / raw) To: Dave Marchevsky Cc: bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > > As part of the road to libbpf 1.0, and discussed in libbpf issue tracker > [0], bpf_program__get_prog_info_linear and its associated structs and > helper functions should be deprecated. The functionality is too specific > to the needs of 'perf', and there's little/no out-of-tree usage to > preclude introduction of a more general helper in the future. > > [0] Closes: https://github.com/libbpf/libbpf/issues/313 styling nit: don't know if it's described anywhere or not, but when people do references like this, they use 2 spaces of indentation. No idea how it came to be, but that's what I did for a while and see others doing the same. > > Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > --- > tools/lib/bpf/libbpf.h | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > index 89ca9c83ed4e..285008b46e1b 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -877,12 +877,15 @@ struct bpf_prog_info_linear { > __u8 data[]; > }; > > +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") > LIBBPF_API struct bpf_prog_info_linear * > bpf_program__get_prog_info_linear(int fd, __u64 arrays); > > +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") > LIBBPF_API void > bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear); > > +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") we can actually deprecate all this starting from v0.6, because perf is building libbpf statically, so no worries about releases (also there are no replacement APIs we have to wait full release for) > LIBBPF_API void > bpf_program__bpil_offs_to_addr(struct bpf_prog_info_linear *info_linear); > > -- > 2.30.2 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear 2021-10-20 17:37 ` Andrii Nakryiko @ 2021-10-20 21:01 ` Toke Høiland-Jørgensen [not found] ` <d3de589a-21f3-7a0d-59de-126d3c70fba1@fb.com> 0 siblings, 1 reply; 13+ messages in thread From: Toke Høiland-Jørgensen @ 2021-10-20 21:01 UTC (permalink / raw) To: Andrii Nakryiko, Dave Marchevsky Cc: bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar Andrii Nakryiko <andrii.nakryiko@gmail.com> writes: > On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: >> >> As part of the road to libbpf 1.0, and discussed in libbpf issue tracker >> [0], bpf_program__get_prog_info_linear and its associated structs and >> helper functions should be deprecated. The functionality is too specific >> to the needs of 'perf', and there's little/no out-of-tree usage to >> preclude introduction of a more general helper in the future. >> >> [0] Closes: https://github.com/libbpf/libbpf/issues/313 > > styling nit: don't know if it's described anywhere or not, but when > people do references like this, they use 2 spaces of indentation. No > idea how it came to be, but that's what I did for a while and see > others doing the same. > >> >> Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> >> --- >> tools/lib/bpf/libbpf.h | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h >> index 89ca9c83ed4e..285008b46e1b 100644 >> --- a/tools/lib/bpf/libbpf.h >> +++ b/tools/lib/bpf/libbpf.h >> @@ -877,12 +877,15 @@ struct bpf_prog_info_linear { >> __u8 data[]; >> }; >> >> +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") >> LIBBPF_API struct bpf_prog_info_linear * >> bpf_program__get_prog_info_linear(int fd, __u64 arrays); >> >> +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") >> LIBBPF_API void >> bpf_program__bpil_addr_to_offs(struct bpf_prog_info_linear *info_linear); >> >> +LIBBPF_DEPRECATED_SINCE(0, 7, "use a custom linear prog_info wrapper") > > we can actually deprecate all this starting from v0.6, because perf is > building libbpf statically, so no worries about releases (also there > are no replacement APIs we have to wait full release for) Just FYI, we're also using this in libxdp, and that does link dynamically to libbpf. It's not an issue to move away from it[0], but perf is not the only user :) -Toke [0] Track that here: https://github.com/xdp-project/xdp-tools/issues/127 ^ permalink raw reply [flat|nested] 13+ messages in thread
[parent not found: <d3de589a-21f3-7a0d-59de-126d3c70fba1@fb.com>]
* Re: [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear [not found] ` <d3de589a-21f3-7a0d-59de-126d3c70fba1@fb.com> @ 2021-10-22 19:26 ` Andrii Nakryiko 0 siblings, 0 replies; 13+ messages in thread From: Andrii Nakryiko @ 2021-10-22 19:26 UTC (permalink / raw) To: Dave Marchevsky Cc: Toke Høiland-Jørgensen, bpf, linux-perf-use., Song Liu, Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar On Fri, Oct 22, 2021 at 12:18 PM Dave Marchevsky <davemarchevsky@fb.com> wrote: > > On 10/20/21 5:01 PM, Toke Høiland-Jørgensen wrote: > > Andrii Nakryiko <andrii.nakryiko@gmail.com> writes: > > > >> On Mon, Oct 11, 2021 at 1:20 AM Dave Marchevsky <davemarchevsky@fb.com> wrote: > >>> > >>> As part of the road to libbpf 1.0, and discussed in libbpf issue tracker > >>> [0], bpf_program__get_prog_info_linear and its associated structs and > >>> helper functions should be deprecated. The functionality is too specific > >>> to the needs of 'perf', and there's little/no out-of-tree usage to > >>> preclude introduction of a more general helper in the future. > >>> > >>> [0] Closes: https://github.com/libbpf/libbpf/issues/313 > >> > >> styling nit: don't know if it's described anywhere or not, but when > >> people do references like this, they use 2 spaces of indentation. No > >> idea how it came to be, but that's what I did for a while and see > >> others doing the same. > >> > >>> > >>> Signed-off-by: Dave Marchevsky <davemarchevsky@fb.com> > >>> --- > > [...] > > >> we can actually deprecate all this starting from v0.6, because perf is > >> building libbpf statically, so no worries about releases (also there > >> are no replacement APIs we have to wait full release for) > > > > Just FYI, we're also using this in libxdp, and that does link > > dynamically to libbpf. It's not an issue to move away from it[0], but > > perf is not the only user :) > > > > -Toke > > > > [0] Track that here: https://github.com/xdp-project/xdp-tools/issues/127 > > > > I submitted a PR to migrate the xdp-tools usage as well. Strange that > this didn't show up in an "all github" search. > > Andrii, should the DEPRECATED_SINCE stay at 0.7 in light of this? There is no replacement API that we need to wait to go through full libbpf release, so no, it can stay as is. ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-10-31 17:13 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-10-11 8:20 [PATCH v2 bpf-next 0/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-11 8:20 ` [PATCH v2 bpf-next 1/4] libbpf: migrate internal use of bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-20 17:36 ` Andrii Nakryiko 2021-10-11 8:20 ` [PATCH v2 bpf-next 2/4] bpftool: use bpf_obj_get_info_by_fd directly Dave Marchevsky 2021-10-20 17:37 ` Andrii Nakryiko 2021-10-20 22:15 ` Quentin Monnet 2021-10-11 8:20 ` [PATCH v2 bpf-next 3/4] perf: pull in bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-20 17:37 ` Andrii Nakryiko [not found] ` <5080FF1F-8E7A-4AF7-AD7E-7349E58CFEDB@fb.com> 2021-10-31 17:13 ` Arnaldo Carvalho de Melo 2021-10-11 8:20 ` [PATCH v2 bpf-next 4/4] libbpf: deprecate bpf_program__get_prog_info_linear Dave Marchevsky 2021-10-20 17:37 ` Andrii Nakryiko 2021-10-20 21:01 ` Toke Høiland-Jørgensen [not found] ` <d3de589a-21f3-7a0d-59de-126d3c70fba1@fb.com> 2021-10-22 19:26 ` Andrii Nakryiko
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.