On Thu, Nov 18, 2021 at 2:33 AM Florent Revest <revest@xxxxxxxxxxxx> wrote: > > Recently, bpf_program__flags and bpf_program__set_extra_flags were > introduced to the libbpf API but they only allow adding load flags. > > We have a use-case where we construct a skeleton with a sleepable > program and if it fails to load then we want to make it non-sleepable by > clearing BPF_F_SLEEPABLE. I'd say the better way to do this is to have two programs (that share the logic, of course) and pick one or another at runtime: static int whatever_logic(bool sleepable) { ... } SEC("fentry.s/whatever") int BPF_PROG(whatever_sleepable, ...) { return whatever_logic(true); } SEC("fentry/whatever") int BPF_PROG(whatever_nonsleepable, ...) { return whatever_logic(false); } Then at runtime you can bpf_program__autoload(..., false) for a variant you don't want to load. This clear_flags business seems too low-level and too limited. Next thing we'll be adding a few more bit manipulation variants (e.g, reset flags). Let's see how far you can get with the use of existing features. I'd set_extra_flags() to be almost never used, btw. And they shouldn't, if can be avoided. So I'm hesitant to keep extending operations around prog_flags. But given we just added set_extra_flags() and it's already too limiting, let's change set_extra flags to just set_flags() that will override the flags with whatever user provides. Then with bpf_program__flags() and bpf_program__set_flags() you can express whatever you want without adding extra APIs. Care to fix that? > > Signed-off-by: Florent Revest <revest@xxxxxxxxxxxx> > --- > tools/lib/bpf/libbpf.c | 9 +++++++++ > tools/lib/bpf/libbpf.h | 1 + > tools/lib/bpf/libbpf.map | 1 + > 3 files changed, 11 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index de7e09a6b5ec..dcb7fced5fd2 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -8305,6 +8305,15 @@ int bpf_program__set_extra_flags(struct bpf_program *prog, __u32 extra_flags) > return 0; > } > > +int bpf_program__clear_flags(struct bpf_program *prog, __u32 flags) > +{ > + if (prog->obj->loaded) > + return libbpf_err(-EBUSY); > + > + prog->prog_flags &= ~flags; > + return 0; > +} > + > #define SEC_DEF(sec_pfx, ptype, atype, flags, ...) { \ > .sec = sec_pfx, \ > .prog_type = BPF_PROG_TYPE_##ptype, \ > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > index 4ec69f224342..08f108e49841 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -495,6 +495,7 @@ bpf_program__set_expected_attach_type(struct bpf_program *prog, > > LIBBPF_API __u32 bpf_program__flags(const struct bpf_program *prog); > LIBBPF_API int bpf_program__set_extra_flags(struct bpf_program *prog, __u32 extra_flags); > +LIBBPF_API int bpf_program__clear_flags(struct bpf_program *prog, __u32 flags); > > LIBBPF_API int > bpf_program__set_attach_target(struct bpf_program *prog, int attach_prog_fd, > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index 6a59514a48cf..eeff700240dc 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -401,6 +401,7 @@ LIBBPF_0.6.0 { > bpf_program__insn_cnt; > bpf_program__insns; > bpf_program__set_extra_flags; > + bpf_program__clear_flags; > btf__add_btf; > btf__add_decl_tag; > btf__add_type_tag; > -- > 2.34.0.rc2.393.gf8c9666880-goog >