libbpf: Support sleepable progs
authorAlexei Starovoitov <ast@kernel.org>
Thu, 27 Aug 2020 22:01:13 +0000 (15:01 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 28 Aug 2020 19:20:33 +0000 (21:20 +0200)
Pass request to load program as sleepable via ".s" suffix in the section name.
If it happens in the future that all map types and helpers are allowed with
BPF_F_SLEEPABLE flag "fmod_ret/" and "lsm/" can be aliased to "fmod_ret.s/" and
"lsm.s/" to make all lsm and fmod_ret programs sleepable by default. The fentry
and fexit programs would always need to have sleepable vs non-sleepable
distinction, since not all fentry/fexit progs will be attached to sleepable
kernel functions.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: KP Singh <kpsingh@google.com>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/20200827220114.69225-5-alexei.starovoitov@gmail.com
tools/lib/bpf/libbpf.c

index 8cdb2528482e9dce6be8554a5a71679044cc4d54..b688aadf09c5dea61c9349305ddeb23bc70152bf 100644 (file)
@@ -208,6 +208,7 @@ struct bpf_sec_def {
        bool is_exp_attach_type_optional;
        bool is_attachable;
        bool is_attach_btf;
+       bool is_sleepable;
        attach_fn_t attach_fn;
 };
 
@@ -6291,6 +6292,8 @@ __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,
                        /* couldn't guess, but user might manually specify */
                        continue;
 
+               if (prog->sec_def->is_sleepable)
+                       prog->prog_flags |= BPF_F_SLEEPABLE;
                bpf_program__set_type(prog, prog->sec_def->prog_type);
                bpf_program__set_expected_attach_type(prog,
                                prog->sec_def->expected_attach_type);
@@ -7559,6 +7562,21 @@ static const struct bpf_sec_def section_defs[] = {
                .expected_attach_type = BPF_TRACE_FEXIT,
                .is_attach_btf = true,
                .attach_fn = attach_trace),
+       SEC_DEF("fentry.s/", TRACING,
+               .expected_attach_type = BPF_TRACE_FENTRY,
+               .is_attach_btf = true,
+               .is_sleepable = true,
+               .attach_fn = attach_trace),
+       SEC_DEF("fmod_ret.s/", TRACING,
+               .expected_attach_type = BPF_MODIFY_RETURN,
+               .is_attach_btf = true,
+               .is_sleepable = true,
+               .attach_fn = attach_trace),
+       SEC_DEF("fexit.s/", TRACING,
+               .expected_attach_type = BPF_TRACE_FEXIT,
+               .is_attach_btf = true,
+               .is_sleepable = true,
+               .attach_fn = attach_trace),
        SEC_DEF("freplace/", EXT,
                .is_attach_btf = true,
                .attach_fn = attach_trace),
@@ -7566,6 +7584,11 @@ static const struct bpf_sec_def section_defs[] = {
                .is_attach_btf = true,
                .expected_attach_type = BPF_LSM_MAC,
                .attach_fn = attach_lsm),
+       SEC_DEF("lsm.s/", LSM,
+               .is_attach_btf = true,
+               .is_sleepable = true,
+               .expected_attach_type = BPF_LSM_MAC,
+               .attach_fn = attach_lsm),
        SEC_DEF("iter/", TRACING,
                .expected_attach_type = BPF_TRACE_ITER,
                .is_attach_btf = true,
@@ -8288,7 +8311,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
 
                prog->prog_ifindex = attr->ifindex;
                prog->log_level = attr->log_level;
-               prog->prog_flags = attr->prog_flags;
+               prog->prog_flags |= attr->prog_flags;
                if (!first_prog)
                        first_prog = prog;
        }