Skip to content

Commit

Permalink
[EXPERIMENT] mass_attacher: try using BPF_F_MULTI_FUNC for fast fentr…
Browse files Browse the repository at this point in the history
…y-based attach

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
  • Loading branch information
anakryiko committed Jun 17, 2021
1 parent 5274e88 commit 8a07bc4
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
5 changes: 4 additions & 1 deletion src/mass_attach.bpf.c
Expand Up @@ -107,13 +107,16 @@ static __always_inline void recur_exit(u32 cpu)

static __always_inline u64 get_ftrace_caller_ip(void *ctx, int arg_cnt)
{
u64 off = 1 /* skip orig rbp */ + 1 /* skip reserved space for ret value */;
//u64 off = 1 /* skip orig rbp */ + 1 /* skip reserved space for ret value */;
u64 off = 8;
u64 ip;

/*
if (arg_cnt <= 6)
off += arg_cnt;
else
off += 6;
*/
off = (u64)ctx + off * 8;

if (bpf_probe_read_kernel(&ip, sizeof(ip), (void *)off))
Expand Down
36 changes: 27 additions & 9 deletions src/mass_attacher.c
Expand Up @@ -397,12 +397,12 @@ int mass_attacher__prepare(struct mass_attacher *att)
bpf_program__set_autoload(att->skel->progs.kexit, false);

for (i = 0; i <= MAX_FUNC_ARG_CNT; i++) {
struct mass_attacher_func_info *finfo;
//struct mass_attacher_func_info *finfo;

if (att->func_info_cnts[i]) {
finfo = &att->func_infos[att->func_info_id_for_arg_cnt[i]];
bpf_program__set_attach_target(att->fentries[i], 0, finfo->name);
bpf_program__set_attach_target(att->fexits[i], 0, finfo->name);
//finfo = &att->func_infos[att->func_info_id_for_arg_cnt[i]];
bpf_program__set_attach_target(att->fentries[i], 0, "arch_prepare_bpf_trampoline");
bpf_program__set_attach_target(att->fexits[i], 0, "arch_prepare_bpf_trampoline");
bpf_program__set_prep(att->fentries[i], 1, hijack_prog);
bpf_program__set_prep(att->fexits[i], 1, hijack_prog);

Expand Down Expand Up @@ -675,6 +675,8 @@ static int hijack_prog(struct bpf_program *prog, int n,
static int clone_prog(const struct bpf_program *prog,
struct bpf_insn *insns, size_t insn_cnt, int attach_btf_id);

static int *btf_ids;

int mass_attacher__load(struct mass_attacher *att)
{
int err, i, map_fd;
Expand All @@ -696,6 +698,12 @@ int mass_attacher__load(struct mass_attacher *att)
if (att->use_fentries && att->debug)
printf("Preparing %d BPF program copies...\n", att->func_cnt * 2);

if (att->use_fentries) {
btf_ids = calloc(att->func_cnt, 4);
for (i = 0; i < att->func_cnt; i++)
btf_ids[i] = att->func_infos[i].btf_id;
}

for (i = 0; i < att->func_cnt; i++) {
struct mass_attacher_func_info *finfo = &att->func_infos[i];
const char *func_name = att->func_infos[i].name;
Expand All @@ -710,7 +718,7 @@ int mass_attacher__load(struct mass_attacher *att)
return err;
}

if (att->use_fentries) {
if (att->use_fentries && i == 0) {
err = clone_prog(att->fentries[finfo->arg_cnt],
att->fentries_insns[finfo->arg_cnt],
att->fentries_insn_cnts[finfo->arg_cnt],
Expand Down Expand Up @@ -749,7 +757,8 @@ static int clone_prog(const struct bpf_program *prog,
attr.insns = insns;
attr.insns_cnt = insn_cnt;
attr.license = "Dual BSD/GPL";
attr.attach_btf_id = attach_btf_id;
attr.attach_btf_id = 0;//attach_btf_id;
attr.prog_flags = BPF_F_MULTI_FUNC;

fd = bpf_load_program_xattr(&attr, NULL, 0);
if (fd < 0)
Expand All @@ -760,7 +769,7 @@ static int clone_prog(const struct bpf_program *prog,

int mass_attacher__attach(struct mass_attacher *att)
{
int i, err;
int i, err = 0;

for (i = 0; i < att->func_cnt; i++) {
struct mass_attacher_func_info *finfo = &att->func_infos[i];
Expand All @@ -770,16 +779,25 @@ int mass_attacher__attach(struct mass_attacher *att)
if (att->use_fentries) {
int prog_fd;

if (i != 0)
continue;

prog_fd = att->func_infos[i].fentry_prog_fd;
err = bpf_raw_tracepoint_open(NULL, prog_fd);
DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts,
.multi_btf_ids = btf_ids,
.multi_btf_ids_cnt = att->func_cnt,
);
//err = bpf_raw_tracepoint_open(NULL, prog_fd);
err = bpf_link_create(prog_fd, 0, BPF_TRACE_FENTRY, &opts);
if (err < 0) {
fprintf(stderr, "Failed to attach FENTRY prog (fd %d) for func #%d (%s) at addr %lx: %d\n",
prog_fd, i + 1, func_name, func_addr, -errno);
return err;
}

prog_fd = att->func_infos[i].fexit_prog_fd;
err = bpf_raw_tracepoint_open(NULL, prog_fd);
//err = bpf_raw_tracepoint_open(NULL, prog_fd);
//err = bpf_link_create(prog_fd, 0, BPF_TRACE_FEXIT, &opts);
if (err < 0) {
fprintf(stderr, "Failed to attach FEXIT prog (fd %d) for func #%d (%s) at addr %lx: %d\n",
prog_fd, i + 1, func_name, func_addr, -errno);
Expand Down

0 comments on commit 8a07bc4

Please sign in to comment.