]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Add bpf_trampoline_add/remove_prog functions
authorJiri Olsa <jolsa@kernel.org>
Sat, 6 Jun 2026 12:39:32 +0000 (14:39 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Sun, 7 Jun 2026 17:03:00 +0000 (10:03 -0700)
Separate bpf_trampoline_add/remove_prog functions from
__bpf_trampoline_link/unlink functions to be able to add/remove
trampoline programs without the image being updated in following
changes. No functional change is intended.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20260606123955.345967-8-jolsa@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/trampoline.c

index 1006031ea0212d654cb7b3cb6021ce03f417c546..701138ef424abe502e3793317ff8bfd3704cdba4 100644 (file)
@@ -820,41 +820,16 @@ static int bpf_freplace_check_tgt_prog(struct bpf_prog *tgt_prog)
        return 0;
 }
 
-static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
-                                     struct bpf_trampoline *tr,
-                                     struct bpf_prog *tgt_prog,
-                                     const struct bpf_trampoline_ops *ops,
-                                     void *data)
+static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
+                                  struct bpf_tramp_link *link,
+                                  int cnt)
 {
        struct bpf_fsession_link *fslink = NULL;
        enum bpf_tramp_prog_type kind;
        struct bpf_tramp_link *link_exiting;
        struct hlist_head *prog_list;
-       int err = 0;
-       int cnt = 0, i;
 
        kind = bpf_attach_type_to_tramp(link->link.prog);
-       if (tr->extension_prog)
-               /* cannot attach fentry/fexit if extension prog is attached.
-                * cannot overwrite extension prog either.
-                */
-               return -EBUSY;
-
-       for (i = 0; i < BPF_TRAMP_MAX; i++)
-               cnt += tr->progs_cnt[i];
-
-       if (kind == BPF_TRAMP_REPLACE) {
-               /* Cannot attach extension if fentry/fexit are in use. */
-               if (cnt)
-                       return -EBUSY;
-               err = bpf_freplace_check_tgt_prog(tgt_prog);
-               if (err)
-                       return err;
-               tr->extension_prog = link->link.prog;
-               return bpf_arch_text_poke(tr->func.addr, BPF_MOD_NOP,
-                                         BPF_MOD_JUMP, NULL,
-                                         link->link.prog->bpf_func);
-       }
        if (kind == BPF_TRAMP_FSESSION) {
                prog_list = &tr->progs_hlist[BPF_TRAMP_FENTRY];
                cnt++;
@@ -882,17 +857,64 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
        } else {
                tr->progs_cnt[kind]++;
        }
-       err = bpf_trampoline_update(tr, true /* lock_direct_mutex */, ops, data);
-       if (err) {
-               hlist_del_init(&link->tramp_hlist);
-               if (kind == BPF_TRAMP_FSESSION) {
-                       tr->progs_cnt[BPF_TRAMP_FENTRY]--;
-                       hlist_del_init(&fslink->fexit.tramp_hlist);
-                       tr->progs_cnt[BPF_TRAMP_FEXIT]--;
-               } else {
-                       tr->progs_cnt[kind]--;
-               }
+       return 0;
+}
+
+static void bpf_trampoline_remove_prog(struct bpf_trampoline *tr,
+                                   struct bpf_tramp_link *link)
+{
+       struct bpf_fsession_link *fslink;
+       enum bpf_tramp_prog_type kind;
+
+       kind = bpf_attach_type_to_tramp(link->link.prog);
+       if (kind == BPF_TRAMP_FSESSION) {
+               fslink = container_of(link, struct bpf_fsession_link, link.link);
+               hlist_del_init(&fslink->fexit.tramp_hlist);
+               tr->progs_cnt[BPF_TRAMP_FEXIT]--;
+               kind = BPF_TRAMP_FENTRY;
+       }
+       hlist_del_init(&link->tramp_hlist);
+       tr->progs_cnt[kind]--;
+}
+
+static int __bpf_trampoline_link_prog(struct bpf_tramp_link *link,
+                                     struct bpf_trampoline *tr,
+                                     struct bpf_prog *tgt_prog,
+                                     const struct bpf_trampoline_ops *ops,
+                                     void *data)
+{
+       enum bpf_tramp_prog_type kind;
+       int err = 0;
+       int cnt = 0, i;
+
+       kind = bpf_attach_type_to_tramp(link->link.prog);
+       if (tr->extension_prog)
+               /* cannot attach fentry/fexit if extension prog is attached.
+                * cannot overwrite extension prog either.
+                */
+               return -EBUSY;
+
+       for (i = 0; i < BPF_TRAMP_MAX; i++)
+               cnt += tr->progs_cnt[i];
+
+       if (kind == BPF_TRAMP_REPLACE) {
+               /* Cannot attach extension if fentry/fexit are in use. */
+               if (cnt)
+                       return -EBUSY;
+               err = bpf_freplace_check_tgt_prog(tgt_prog);
+               if (err)
+                       return err;
+               tr->extension_prog = link->link.prog;
+               return bpf_arch_text_poke(tr->func.addr, BPF_MOD_NOP,
+                                         BPF_MOD_JUMP, NULL,
+                                         link->link.prog->bpf_func);
        }
+       err = bpf_trampoline_add_prog(tr, link, cnt);
+       if (err)
+               return err;
+       err = bpf_trampoline_update(tr, true /* lock_direct_mutex */, ops, data);
+       if (err)
+               bpf_trampoline_remove_prog(tr, link);
        return err;
 }
 
@@ -927,16 +949,8 @@ static int __bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
                guard(mutex)(&tgt_prog->aux->ext_mutex);
                tgt_prog->aux->is_extended = false;
                return err;
-       } else if (kind == BPF_TRAMP_FSESSION) {
-               struct bpf_fsession_link *fslink =
-                       container_of(link, struct bpf_fsession_link, link.link);
-
-               hlist_del_init(&fslink->fexit.tramp_hlist);
-               tr->progs_cnt[BPF_TRAMP_FEXIT]--;
-               kind = BPF_TRAMP_FENTRY;
        }
-       hlist_del_init(&link->tramp_hlist);
-       tr->progs_cnt[kind]--;
+       bpf_trampoline_remove_prog(tr, link);
        return bpf_trampoline_update(tr, true /* lock_direct_mutex */, ops, data);
 }