Re: [PATCH 1/2] perf tools: Add more weak libbpf functions
From: Andrii Nakryiko
Date: Wed Nov 10 2021 - 17:38:07 EST
On Wed, Nov 10, 2021 at 12:45 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote:
>
> On Tue, Nov 09, 2021 at 03:33:04PM -0800, Andrii Nakryiko wrote:
> > On Tue, Nov 9, 2021 at 10:50 AM Ian Rogers <irogers@xxxxxxxxxx> wrote:
> > >
> > > On Tue, Nov 9, 2021 at 6:07 AM Jiri Olsa <jolsa@xxxxxxxxxx> wrote:
> > > >
> > > > We hit the window where perf uses libbpf functions, that did not
> > > > make it to the official libbpf release yet and it's breaking perf
> > > > build with dynamicly linked libbpf.
> > > >
> > > > Fixing this by providing the new interface as weak functions which
> > > > calls the original libbpf functions. Fortunatelly the changes were
> > > > just renames.
> > >
> > > Could we just provide these functions behind a libbpf version #if ?
> > > Weak symbols break things in subtle ways, under certain circumstances
> > > the weak symbol is preferred over the strong due to lazy object file
> > > resolution:
> > > https://maskray.me/blog/2021-06-20-symbol-processing#archive-processing
> > > This bit me last week, but in general you get away with it as the lazy
> > > object file will get processed in an archive exposing the strong
> > > symbol. With an #if you either get a linker error for 2 definitions or
> > > 0 definitions, and it's clear what is broken.
> > >
> > > In the past we had problems due to constant propagation from weak
> > > const variables, where #if was the solution:
> > > https://lore.kernel.org/lkml/20191001003623.255186-1-irogers@xxxxxxxxxx/
> > >
> > > There was some recent conversation on libbpf version for pahole here:
> > > https://lore.kernel.org/bpf/CAP-5=fUc3LtU0WYg-Py9Jf+9picaWHJdSw=sdOMA54uY3p1pdw@xxxxxxxxxxxxxx/T/
> > > https://lore.kernel.org/bpf/20211021183330.460681-1-irogers@xxxxxxxxxx/
> > >
> > > Thanks,
> > > Ian
> > >
> > > > Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx>
> > > > ---
> > > > tools/perf/util/bpf-event.c | 27 +++++++++++++++++++++++++++
> > > > 1 file changed, 27 insertions(+)
> > > >
> > > > diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
> > > > index 4d3b4cdce176..ceb96360fd12 100644
> > > > --- a/tools/perf/util/bpf-event.c
> > > > +++ b/tools/perf/util/bpf-event.c
> > > > @@ -33,6 +33,33 @@ struct btf * __weak btf__load_from_kernel_by_id(__u32 id)
> > > > return err ? ERR_PTR(err) : btf;
> > > > }
> > > >
> > > > +struct bpf_program * __weak
> > > > +bpf_object__next_program(const struct bpf_object *obj, struct bpf_program *prev)
> > > > +{
> > > > +#pragma GCC diagnostic push
> > > > +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> > > > + return bpf_program__next(prev, obj);
> > > > +#pragma GCC diagnostic pop
> > > > +}
> > > > +
> > > > +struct bpf_map * __weak
> > > > +bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev)
> > > > +{
> > > > +#pragma GCC diagnostic push
> > > > +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> > > > + return bpf_map__next(prev, obj);
> > > > +#pragma GCC diagnostic pop
> > > > +}
> > > > +
> > > > +const void * __weak
> > > > +btf__raw_data(const struct btf *btf_ro, __u32 *size)
> > > > +{
> > > > +#pragma GCC diagnostic push
> > > > +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> > > > + return btf__get_raw_data(btf_ro, size);
> >
> > you can still use old variants for the time being, if you want. Were
> > new APIs used accidentally? Libbpf maintains a guarantee that if some
> > API is deprecated in favor of the new one, there will be at least one
> > full libbpf release where both APIs are available and not marked as
> > deprecated.
>
> we could use old api instead of btf__raw_data, we could just revert
> the perf change
>
> but bpf_object__next_program and bpf_object__next_map are used through
> macros like bpf_object__for_each_map or bpf_object__for_each_program,
> so we'd need to define 'old versions' of them
There is nothing magical about bpf_object__for_each_map(). If it's
causing problems, just implement your own iteration logic. You'll be
suffering like this because you are trying to support both shared
library mode and static library mode with libbpf. I'm sorry for your
pain, but you are trying to compile against the latest unreleased
headers, yet work properly with older released libbpf shared library.
It's painful and you know what I think about using shared libraries,
right?
>
> jirka
>
> >
> >
> > > > +#pragma GCC diagnostic pop
> > > > +}
> > > > +
> > > > static int snprintf_hex(char *buf, size_t size, unsigned char *data, size_t len)
> > > > {
> > > > int ret = 0;
> > > > --
> > > > 2.31.1
> > > >
> >
>