libbpf: remove internal multi-instance prog support
authorAndrii Nakryiko <andrii@kernel.org>
Mon, 27 Jun 2022 21:15:23 +0000 (14:15 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 28 Jun 2022 20:13:33 +0000 (13:13 -0700)
Clean up internals that had to deal with the possibility of
multi-instance bpf_programs. Libbpf 1.0 doesn't support this, so all
this is not necessary now and can be simplified.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20220627211527.2245459-12-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/lib/bpf/libbpf.c

index fe98789d1776966d0a45be62a7810636e6daef93..65f2a57bc78d3c36b049ecaec773e0630ceeb47a 100644 (file)
@@ -366,16 +366,6 @@ struct bpf_sec_def {
        libbpf_prog_attach_fn_t prog_attach_fn;
 };
 
-struct bpf_prog_prep_result {
-       struct bpf_insn *new_insn_ptr;
-       int new_insn_cnt;
-       int *pfd;
-};
-
-typedef int (*bpf_program_prep_t)(struct bpf_program *prog, int n,
-                                 struct bpf_insn *insns, int insns_cnt,
-                                 struct bpf_prog_prep_result *res);
-
 /*
  * bpf_prog should be a better name but it has been used in
  * linux/filter.h.
@@ -429,22 +419,19 @@ struct bpf_program {
        size_t log_size;
        __u32 log_level;
 
-       struct {
-               int nr;
-               int *fds;
-       } instances;
-       bpf_program_prep_t preprocessor;
-
        struct bpf_object *obj;
 
+       int fd;
        bool autoload;
        bool mark_btf_static;
        enum bpf_prog_type type;
        enum bpf_attach_type expected_attach_type;
+
        int prog_ifindex;
        __u32 attach_btf_obj_fd;
        __u32 attach_btf_id;
        __u32 attach_prog_fd;
+
        void *func_info;
        __u32 func_info_rec_size;
        __u32 func_info_cnt;
@@ -695,25 +682,10 @@ static Elf64_Rel *elf_rel_by_idx(Elf_Data *data, size_t idx);
 
 void bpf_program__unload(struct bpf_program *prog)
 {
-       int i;
-
        if (!prog)
                return;
 
-       /*
-        * If the object is opened but the program was never loaded,
-        * it is possible that prog->instances.nr == -1.
-        */
-       if (prog->instances.nr > 0) {
-               for (i = 0; i < prog->instances.nr; i++)
-                       zclose(prog->instances.fds[i]);
-       } else if (prog->instances.nr != -1) {
-               pr_warn("Internal error: instances.nr is %d\n",
-                       prog->instances.nr);
-       }
-
-       prog->instances.nr = -1;
-       zfree(&prog->instances.fds);
+       zclose(prog->fd);
 
        zfree(&prog->func_info);
        zfree(&prog->line_info);
@@ -797,6 +769,7 @@ bpf_object__init_prog(struct bpf_object *obj, struct bpf_program *prog,
        prog->insns_cnt = prog->sec_insn_cnt;
 
        prog->type = BPF_PROG_TYPE_UNSPEC;
+       prog->fd = -1;
 
        /* libbpf's convention for SEC("?abc...") is that it's just like
         * SEC("abc...") but the corresponding bpf_program starts out with
@@ -810,9 +783,6 @@ bpf_object__init_prog(struct bpf_object *obj, struct bpf_program *prog,
                prog->autoload = true;
        }
 
-       prog->instances.fds = NULL;
-       prog->instances.nr = -1;
-
        /* inherit object's log_level */
        prog->log_level = obj->log_level;
 
@@ -6862,10 +6832,9 @@ static int libbpf_prepare_prog_load(struct bpf_program *prog,
 
 static void fixup_verifier_log(struct bpf_program *prog, char *buf, size_t buf_sz);
 
-static int bpf_object_load_prog_instance(struct bpf_object *obj, struct bpf_program *prog,
-                                        struct bpf_insn *insns, int insns_cnt,
-                                        const char *license, __u32 kern_version,
-                                        int *prog_fd)
+static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog,
+                               struct bpf_insn *insns, int insns_cnt,
+                               const char *license, __u32 kern_version, int *prog_fd)
 {
        LIBBPF_OPTS(bpf_prog_load_opts, load_attr);
        const char *prog_name = NULL;
@@ -7232,88 +7201,6 @@ static int bpf_program_record_relos(struct bpf_program *prog)
        return 0;
 }
 
-static int bpf_object_load_prog(struct bpf_object *obj, struct bpf_program *prog,
-                               const char *license, __u32 kern_ver)
-{
-       int err = 0, fd, i;
-
-       if (obj->loaded) {
-               pr_warn("prog '%s': can't load after object was loaded\n", prog->name);
-               return libbpf_err(-EINVAL);
-       }
-
-       if (prog->instances.nr < 0 || !prog->instances.fds) {
-               if (prog->preprocessor) {
-                       pr_warn("Internal error: can't load program '%s'\n",
-                               prog->name);
-                       return libbpf_err(-LIBBPF_ERRNO__INTERNAL);
-               }
-
-               prog->instances.fds = malloc(sizeof(int));
-               if (!prog->instances.fds) {
-                       pr_warn("Not enough memory for BPF fds\n");
-                       return libbpf_err(-ENOMEM);
-               }
-               prog->instances.nr = 1;
-               prog->instances.fds[0] = -1;
-       }
-
-       if (!prog->preprocessor) {
-               if (prog->instances.nr != 1) {
-                       pr_warn("prog '%s': inconsistent nr(%d) != 1\n",
-                               prog->name, prog->instances.nr);
-               }
-               if (obj->gen_loader)
-                       bpf_program_record_relos(prog);
-               err = bpf_object_load_prog_instance(obj, prog,
-                                                   prog->insns, prog->insns_cnt,
-                                                   license, kern_ver, &fd);
-               if (!err)
-                       prog->instances.fds[0] = fd;
-               goto out;
-       }
-
-       for (i = 0; i < prog->instances.nr; i++) {
-               struct bpf_prog_prep_result result;
-               bpf_program_prep_t preprocessor = prog->preprocessor;
-
-               memset(&result, 0, sizeof(result));
-               err = preprocessor(prog, i, prog->insns,
-                                  prog->insns_cnt, &result);
-               if (err) {
-                       pr_warn("Preprocessing the %dth instance of program '%s' failed\n",
-                               i, prog->name);
-                       goto out;
-               }
-
-               if (!result.new_insn_ptr || !result.new_insn_cnt) {
-                       pr_debug("Skip loading the %dth instance of program '%s'\n",
-                                i, prog->name);
-                       prog->instances.fds[i] = -1;
-                       if (result.pfd)
-                               *result.pfd = -1;
-                       continue;
-               }
-
-               err = bpf_object_load_prog_instance(obj, prog,
-                                                   result.new_insn_ptr, result.new_insn_cnt,
-                                                   license, kern_ver, &fd);
-               if (err) {
-                       pr_warn("Loading the %dth instance of program '%s' failed\n",
-                               i, prog->name);
-                       goto out;
-               }
-
-               if (result.pfd)
-                       *result.pfd = fd;
-               prog->instances.fds[i] = fd;
-       }
-out:
-       if (err)
-               pr_warn("failed to load program '%s'\n", prog->name);
-       return libbpf_err(err);
-}
-
 static int
 bpf_object__load_progs(struct bpf_object *obj, int log_level)
 {
@@ -7337,9 +7224,16 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level)
                        continue;
                }
                prog->log_level |= log_level;
-               err = bpf_object_load_prog(obj, prog, obj->license, obj->kern_version);
-               if (err)
+
+               if (obj->gen_loader)
+                       bpf_program_record_relos(prog);
+
+               err = bpf_object_load_prog(obj, prog, prog->insns, prog->insns_cnt,
+                                          obj->license, obj->kern_version, &prog->fd);
+               if (err) {
+                       pr_warn("prog '%s': failed to load: %d\n", prog->name, err);
                        return err;
+               }
        }
 
        bpf_object__free_relocs(obj);
@@ -7985,11 +7879,16 @@ static int check_path(const char *path)
        return err;
 }
 
-static int bpf_program_pin_instance(struct bpf_program *prog, const char *path, int instance)
+int bpf_program__pin(struct bpf_program *prog, const char *path)
 {
        char *cp, errmsg[STRERR_BUFSIZE];
        int err;
 
+       if (prog->fd < 0) {
+               pr_warn("prog '%s': can't pin program that wasn't loaded\n", prog->name);
+               return libbpf_err(-EINVAL);
+       }
+
        err = make_parent_dir(path);
        if (err)
                return libbpf_err(err);
@@ -7998,164 +7897,35 @@ static int bpf_program_pin_instance(struct bpf_program *prog, const char *path,
        if (err)
                return libbpf_err(err);
 
-       if (prog == NULL) {
-               pr_warn("invalid program pointer\n");
-               return libbpf_err(-EINVAL);
-       }
-
-       if (instance < 0 || instance >= prog->instances.nr) {
-               pr_warn("invalid prog instance %d of prog %s (max %d)\n",
-                       instance, prog->name, prog->instances.nr);
-               return libbpf_err(-EINVAL);
-       }
-
-       if (bpf_obj_pin(prog->instances.fds[instance], path)) {
+       if (bpf_obj_pin(prog->fd, path)) {
                err = -errno;
                cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));
-               pr_warn("failed to pin program: %s\n", cp);
+               pr_warn("prog '%s': failed to pin at '%s': %s\n", prog->name, path, cp);
                return libbpf_err(err);
        }
-       pr_debug("pinned program '%s'\n", path);
 
+       pr_debug("prog '%s': pinned at '%s'\n", prog->name, path);
        return 0;
 }
 
-static int bpf_program_unpin_instance(struct bpf_program *prog, const char *path, int instance)
+int bpf_program__unpin(struct bpf_program *prog, const char *path)
 {
        int err;
 
-       err = check_path(path);
-       if (err)
-               return libbpf_err(err);
-
-       if (prog == NULL) {
-               pr_warn("invalid program pointer\n");
+       if (prog->fd < 0) {
+               pr_warn("prog '%s': can't unpin program that wasn't loaded\n", prog->name);
                return libbpf_err(-EINVAL);
        }
 
-       if (instance < 0 || instance >= prog->instances.nr) {
-               pr_warn("invalid prog instance %d of prog %s (max %d)\n",
-                       instance, prog->name, prog->instances.nr);
-               return libbpf_err(-EINVAL);
-       }
-
-       err = unlink(path);
-       if (err != 0)
-               return libbpf_err(-errno);
-
-       pr_debug("unpinned program '%s'\n", path);
-
-       return 0;
-}
-
-int bpf_program__pin(struct bpf_program *prog, const char *path)
-{
-       int i, err;
-
-       err = make_parent_dir(path);
-       if (err)
-               return libbpf_err(err);
-
-       err = check_path(path);
-       if (err)
-               return libbpf_err(err);
-
-       if (prog == NULL) {
-               pr_warn("invalid program pointer\n");
-               return libbpf_err(-EINVAL);
-       }
-
-       if (prog->instances.nr <= 0) {
-               pr_warn("no instances of prog %s to pin\n", prog->name);
-               return libbpf_err(-EINVAL);
-       }
-
-       if (prog->instances.nr == 1) {
-               /* don't create subdirs when pinning single instance */
-               return bpf_program_pin_instance(prog, path, 0);
-       }
-
-       for (i = 0; i < prog->instances.nr; i++) {
-               char buf[PATH_MAX];
-               int len;
-
-               len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
-               if (len < 0) {
-                       err = -EINVAL;
-                       goto err_unpin;
-               } else if (len >= PATH_MAX) {
-                       err = -ENAMETOOLONG;
-                       goto err_unpin;
-               }
-
-               err = bpf_program_pin_instance(prog, buf, i);
-               if (err)
-                       goto err_unpin;
-       }
-
-       return 0;
-
-err_unpin:
-       for (i = i - 1; i >= 0; i--) {
-               char buf[PATH_MAX];
-               int len;
-
-               len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
-               if (len < 0)
-                       continue;
-               else if (len >= PATH_MAX)
-                       continue;
-
-               bpf_program_unpin_instance(prog, buf, i);
-       }
-
-       rmdir(path);
-
-       return libbpf_err(err);
-}
-
-int bpf_program__unpin(struct bpf_program *prog, const char *path)
-{
-       int i, err;
-
        err = check_path(path);
        if (err)
                return libbpf_err(err);
 
-       if (prog == NULL) {
-               pr_warn("invalid program pointer\n");
-               return libbpf_err(-EINVAL);
-       }
-
-       if (prog->instances.nr <= 0) {
-               pr_warn("no instances of prog %s to pin\n", prog->name);
-               return libbpf_err(-EINVAL);
-       }
-
-       if (prog->instances.nr == 1) {
-               /* don't create subdirs when pinning single instance */
-               return bpf_program_unpin_instance(prog, path, 0);
-       }
-
-       for (i = 0; i < prog->instances.nr; i++) {
-               char buf[PATH_MAX];
-               int len;
-
-               len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
-               if (len < 0)
-                       return libbpf_err(-EINVAL);
-               else if (len >= PATH_MAX)
-                       return libbpf_err(-ENAMETOOLONG);
-
-               err = bpf_program_unpin_instance(prog, buf, i);
-               if (err)
-                       return err;
-       }
-
-       err = rmdir(path);
+       err = unlink(path);
        if (err)
                return libbpf_err(-errno);
 
+       pr_debug("prog '%s': unpinned from '%s'\n", prog->name, path);
        return 0;
 }
 
@@ -8672,13 +8442,6 @@ int bpf_program__set_autoload(struct bpf_program *prog, bool autoload)
        return 0;
 }
 
-static int bpf_program_nth_fd(const struct bpf_program *prog, int n);
-
-int bpf_program__fd(const struct bpf_program *prog)
-{
-       return bpf_program_nth_fd(prog, 0);
-}
-
 const struct bpf_insn *bpf_program__insns(const struct bpf_program *prog)
 {
        return prog->insns;
@@ -8709,27 +8472,15 @@ int bpf_program__set_insns(struct bpf_program *prog,
        return 0;
 }
 
-static int bpf_program_nth_fd(const struct bpf_program *prog, int n)
+int bpf_program__fd(const struct bpf_program *prog)
 {
-       int fd;
-
        if (!prog)
                return libbpf_err(-EINVAL);
 
-       if (n >= prog->instances.nr || n < 0) {
-               pr_warn("Can't get the %dth fd from program %s: only %d instances\n",
-                       n, prog->name, prog->instances.nr);
-               return libbpf_err(-EINVAL);
-       }
-
-       fd = prog->instances.fds[n];
-       if (fd < 0) {
-               pr_warn("%dth instance of program '%s' is invalid\n",
-                       n, prog->name);
+       if (prog->fd < 0)
                return libbpf_err(-ENOENT);
-       }
 
-       return fd;
+       return prog->fd;
 }
 
 __alias(bpf_program__type)