Skip to content

Commit 3aac1ea

Browse files
tohojoAlexei Starovoitov
authored andcommitted
bpf: Move prog->aux->linked_prog and trampoline into bpf_link on attach
In preparation for allowing multiple attachments of freplace programs, move the references to the target program and trampoline into the bpf_tracing_link structure when that is created. To do this atomically, introduce a new mutex in prog->aux to protect writing to the two pointers to target prog and trampoline, and rename the members to make it clear that they are related. With this change, it is no longer possible to attach the same tracing program multiple times (detaching in-between), since the reference from the tracing program to the target disappears on the first attach. However, since the next patch will let the caller supply an attach target, that will also make it possible to attach to the same place multiple times. Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Andrii Nakryiko <andriin@fb.com> Link: https://lore.kernel.org/bpf/160138355059.48470.2503076992210324984.stgit@toke.dk
1 parent 85e3f31 commit 3aac1ea

File tree

8 files changed

+298
-259
lines changed

8 files changed

+298
-259
lines changed

include/linux/bpf.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,8 @@ static __always_inline unsigned int bpf_dispatcher_nop_func(
640640
return bpf_func(ctx, insnsi);
641641
}
642642
#ifdef CONFIG_BPF_JIT
643-
int bpf_trampoline_link_prog(struct bpf_prog *prog);
644-
int bpf_trampoline_unlink_prog(struct bpf_prog *prog);
643+
int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
644+
int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
645645
struct bpf_trampoline *bpf_trampoline_get(u64 key,
646646
struct bpf_attach_target_info *tgt_info);
647647
void bpf_trampoline_put(struct bpf_trampoline *tr);
@@ -688,11 +688,13 @@ void bpf_image_ksym_del(struct bpf_ksym *ksym);
688688
void bpf_ksym_add(struct bpf_ksym *ksym);
689689
void bpf_ksym_del(struct bpf_ksym *ksym);
690690
#else
691-
static inline int bpf_trampoline_link_prog(struct bpf_prog *prog)
691+
static inline int bpf_trampoline_link_prog(struct bpf_prog *prog,
692+
struct bpf_trampoline *tr)
692693
{
693694
return -ENOTSUPP;
694695
}
695-
static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog)
696+
static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog,
697+
struct bpf_trampoline *tr)
696698
{
697699
return -ENOTSUPP;
698700
}
@@ -763,15 +765,16 @@ struct bpf_prog_aux {
763765
u32 max_rdonly_access;
764766
u32 max_rdwr_access;
765767
const struct bpf_ctx_arg_aux *ctx_arg_info;
766-
struct bpf_prog *linked_prog;
768+
struct mutex dst_mutex; /* protects dst_* pointers below, *after* prog becomes visible */
769+
struct bpf_prog *dst_prog;
770+
struct bpf_trampoline *dst_trampoline;
767771
bool verifier_zext; /* Zero extensions has been inserted by verifier. */
768772
bool offload_requested;
769773
bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */
770774
bool func_proto_unreliable;
771775
bool sleepable;
772776
bool tail_call_reachable;
773777
enum bpf_tramp_prog_type trampoline_prog_type;
774-
struct bpf_trampoline *trampoline;
775778
struct hlist_node tramp_hlist;
776779
/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
777780
const struct btf_type *attach_func_proto;

kernel/bpf/btf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4428,7 +4428,7 @@ struct btf *btf_parse_vmlinux(void)
44284428

44294429
struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog)
44304430
{
4431-
struct bpf_prog *tgt_prog = prog->aux->linked_prog;
4431+
struct bpf_prog *tgt_prog = prog->aux->dst_prog;
44324432

44334433
if (tgt_prog) {
44344434
return tgt_prog->aux->btf;
@@ -4455,7 +4455,7 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,
44554455
struct bpf_insn_access_aux *info)
44564456
{
44574457
const struct btf_type *t = prog->aux->attach_func_proto;
4458-
struct bpf_prog *tgt_prog = prog->aux->linked_prog;
4458+
struct bpf_prog *tgt_prog = prog->aux->dst_prog;
44594459
struct btf *btf = bpf_prog_get_target_btf(prog);
44604460
const char *tname = prog->aux->attach_func_name;
44614461
struct bpf_verifier_log *log = info->log;
@@ -5281,7 +5281,7 @@ int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog,
52815281
return -EFAULT;
52825282
}
52835283
if (prog_type == BPF_PROG_TYPE_EXT)
5284-
prog_type = prog->aux->linked_prog->type;
5284+
prog_type = prog->aux->dst_prog->type;
52855285

52865286
t = btf_type_by_id(btf, t->type);
52875287
if (!t || !btf_type_is_func_proto(t)) {

kernel/bpf/core.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
9999

100100
INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode);
101101
mutex_init(&fp->aux->used_maps_mutex);
102+
mutex_init(&fp->aux->dst_mutex);
102103

103104
return fp;
104105
}
@@ -255,6 +256,7 @@ void __bpf_prog_free(struct bpf_prog *fp)
255256
{
256257
if (fp->aux) {
257258
mutex_destroy(&fp->aux->used_maps_mutex);
259+
mutex_destroy(&fp->aux->dst_mutex);
258260
free_percpu(fp->aux->stats);
259261
kfree(fp->aux->poke_tab);
260262
kfree(fp->aux);
@@ -2138,7 +2140,8 @@ static void bpf_prog_free_deferred(struct work_struct *work)
21382140
if (aux->prog->has_callchain_buf)
21392141
put_callchain_buffers();
21402142
#endif
2141-
bpf_trampoline_put(aux->trampoline);
2143+
if (aux->dst_trampoline)
2144+
bpf_trampoline_put(aux->dst_trampoline);
21422145
for (i = 0; i < aux->func_cnt; i++)
21432146
bpf_jit_free(aux->func[i]);
21442147
if (aux->func_cnt) {
@@ -2154,8 +2157,8 @@ void bpf_prog_free(struct bpf_prog *fp)
21542157
{
21552158
struct bpf_prog_aux *aux = fp->aux;
21562159

2157-
if (aux->linked_prog)
2158-
bpf_prog_put(aux->linked_prog);
2160+
if (aux->dst_prog)
2161+
bpf_prog_put(aux->dst_prog);
21592162
INIT_WORK(&aux->work, bpf_prog_free_deferred);
21602163
schedule_work(&aux->work);
21612164
}

kernel/bpf/preload/iterators/iterators.bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct bpf_prog_aux {
4242
__u32 id;
4343
char name[16];
4444
const char *attach_func_name;
45-
struct bpf_prog *linked_prog;
45+
struct bpf_prog *dst_prog;
4646
struct bpf_func_info *func_info;
4747
struct btf *btf;
4848
};
@@ -108,7 +108,7 @@ int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx)
108108

109109
BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id,
110110
get_name(aux->btf, aux->func_info[0].type_id, aux->name),
111-
aux->attach_func_name, aux->linked_prog->aux->name);
111+
aux->attach_func_name, aux->dst_prog->aux->name);
112112
return 0;
113113
}
114114
char LICENSE[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)