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
115 lines
2.3 KiB
C
115 lines
2.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) 2020 Facebook */
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#include <bpf/bpf_core_read.h>
|
|
|
|
#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
|
|
struct seq_file;
|
|
struct bpf_iter_meta {
|
|
struct seq_file *seq;
|
|
__u64 session_id;
|
|
__u64 seq_num;
|
|
};
|
|
|
|
struct bpf_map {
|
|
__u32 id;
|
|
char name[16];
|
|
__u32 max_entries;
|
|
};
|
|
|
|
struct bpf_iter__bpf_map {
|
|
struct bpf_iter_meta *meta;
|
|
struct bpf_map *map;
|
|
};
|
|
|
|
struct btf_type {
|
|
__u32 name_off;
|
|
};
|
|
|
|
struct btf_header {
|
|
__u32 str_len;
|
|
};
|
|
|
|
struct btf {
|
|
const char *strings;
|
|
struct btf_type **types;
|
|
struct btf_header hdr;
|
|
};
|
|
|
|
struct bpf_prog_aux {
|
|
__u32 id;
|
|
char name[16];
|
|
const char *attach_func_name;
|
|
struct bpf_prog *dst_prog;
|
|
struct bpf_func_info *func_info;
|
|
struct btf *btf;
|
|
};
|
|
|
|
struct bpf_prog {
|
|
struct bpf_prog_aux *aux;
|
|
};
|
|
|
|
struct bpf_iter__bpf_prog {
|
|
struct bpf_iter_meta *meta;
|
|
struct bpf_prog *prog;
|
|
};
|
|
#pragma clang attribute pop
|
|
|
|
static const char *get_name(struct btf *btf, long btf_id, const char *fallback)
|
|
{
|
|
struct btf_type **types, *t;
|
|
unsigned int name_off;
|
|
const char *str;
|
|
|
|
if (!btf)
|
|
return fallback;
|
|
str = btf->strings;
|
|
types = btf->types;
|
|
bpf_probe_read_kernel(&t, sizeof(t), types + btf_id);
|
|
name_off = BPF_CORE_READ(t, name_off);
|
|
if (name_off >= btf->hdr.str_len)
|
|
return fallback;
|
|
return str + name_off;
|
|
}
|
|
|
|
SEC("iter/bpf_map")
|
|
int dump_bpf_map(struct bpf_iter__bpf_map *ctx)
|
|
{
|
|
struct seq_file *seq = ctx->meta->seq;
|
|
__u64 seq_num = ctx->meta->seq_num;
|
|
struct bpf_map *map = ctx->map;
|
|
|
|
if (!map)
|
|
return 0;
|
|
|
|
if (seq_num == 0)
|
|
BPF_SEQ_PRINTF(seq, " id name max_entries\n");
|
|
|
|
BPF_SEQ_PRINTF(seq, "%4u %-16s%6d\n", map->id, map->name, map->max_entries);
|
|
return 0;
|
|
}
|
|
|
|
SEC("iter/bpf_prog")
|
|
int dump_bpf_prog(struct bpf_iter__bpf_prog *ctx)
|
|
{
|
|
struct seq_file *seq = ctx->meta->seq;
|
|
__u64 seq_num = ctx->meta->seq_num;
|
|
struct bpf_prog *prog = ctx->prog;
|
|
struct bpf_prog_aux *aux;
|
|
|
|
if (!prog)
|
|
return 0;
|
|
|
|
aux = prog->aux;
|
|
if (seq_num == 0)
|
|
BPF_SEQ_PRINTF(seq, " id name attached\n");
|
|
|
|
BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id,
|
|
get_name(aux->btf, aux->func_info[0].type_id, aux->name),
|
|
aux->attach_func_name, aux->dst_prog->aux->name);
|
|
return 0;
|
|
}
|
|
char LICENSE[] SEC("license") = "GPL";
|