Skip to content

Commit

Permalink
libbpf-tools: Allow biostacks to run on old kernels
Browse files Browse the repository at this point in the history
Fallback to use kprobes if kernel lacks support for fentry/fexit.

Signed-off-by: mickey_zhu <[email protected]>
  • Loading branch information
michael-chuh committed May 19, 2023
1 parent 46a125d commit e54191e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 44 deletions.
63 changes: 49 additions & 14 deletions libbpf-tools/biostacks.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,7 @@ int trace_start(void *ctx, struct request *rq, bool merge_bio)
return 0;
}

SEC("fentry/blk_account_io_start")
int BPF_PROG(blk_account_io_start, struct request *rq)
{
return trace_start(ctx, rq, false);
}

SEC("kprobe/blk_account_io_merge_bio")
int BPF_KPROBE(blk_account_io_merge_bio, struct request *rq)
{
return trace_start(ctx, rq, true);
}

SEC("fentry/blk_account_io_done")
int BPF_PROG(blk_account_io_done, struct request *rq)
static int trace_done(void *ctx, struct request *rq)
{
u64 slot, ts = bpf_ktime_get_ns();
struct internal_rqinfo *i_rqinfop;
Expand Down Expand Up @@ -110,4 +97,52 @@ int BPF_PROG(blk_account_io_done, struct request *rq)
return 0;
}

SEC("fentry/blk_account_io_start")
int BPF_PROG(blk_account_io_start, struct request *rq)
{
return trace_start(ctx, rq, false);
}

SEC("fentry/blk_account_io_done")
int BPF_PROG(blk_account_io_done, struct request *rq)
{
return trace_done(ctx, rq);
}

SEC("fentry/blk_account_io_merge_bio")
int BPF_PROG(blk_account_io_merge_bio, struct request *rq)
{
return trace_start(ctx, rq, true);
}

SEC("kprobe/blk_account_io_start")
int BPF_KPROBE(kprobe_blk_account_io_start, struct request *rq)
{
return trace_start(ctx, rq, false);
}

SEC("kprobe/blk_account_io_done")
int BPF_KPROBE(kprobe_blk_account_io_done, struct request *rq)
{
return trace_done(ctx, rq);
}

SEC("kprobe/__blk_account_io_start")
int BPF_KPROBE(kprobe___blk_account_io_start, struct request *rq)
{
return trace_start(ctx, rq, false);
}

SEC("kprobe/__blk_account_io_done")
int BPF_KPROBE(kprobe___blk_account_io_done, struct request *rq)
{
return trace_done(ctx, rq);
}

SEC("kprobe/blk_account_io_merge_bio")
int BPF_KPROBE(kprobe_blk_account_io_merge_bio, struct request *rq)
{
return trace_start(ctx, rq, true);
}

char LICENSE[] SEC("license") = "GPL";
65 changes: 35 additions & 30 deletions libbpf-tools/biostacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,38 @@ int main(int argc, char **argv)

obj->rodata->targ_ms = env.milliseconds;

if (fentry_can_attach("blk_account_io_start", NULL)) {
bpf_program__set_attach_target(obj->progs.blk_account_io_start, 0,
"blk_account_io_start");
bpf_program__set_attach_target(obj->progs.blk_account_io_done, 0,
"blk_account_io_done");
if (fentry_can_attach("blk_account_io_merge_bio", NULL)) {
bpf_program__set_autoload(obj->progs.kprobe_blk_account_io_merge_bio, false);
bpf_program__set_autoload(obj->progs.kprobe_blk_account_io_start, false);
bpf_program__set_autoload(obj->progs.kprobe_blk_account_io_done, false);
bpf_program__set_autoload(obj->progs.kprobe___blk_account_io_start, false);
bpf_program__set_autoload(obj->progs.kprobe___blk_account_io_done, false);

if (fentry_can_attach("blk_account_io_start", NULL)) {
bpf_program__set_attach_target(obj->progs.blk_account_io_start, 0,
"blk_account_io_start");
bpf_program__set_attach_target(obj->progs.blk_account_io_done, 0,
"blk_account_io_done");
} else {
bpf_program__set_attach_target(obj->progs.blk_account_io_start, 0,
"__blk_account_io_start");
bpf_program__set_attach_target(obj->progs.blk_account_io_done, 0,
"__blk_account_io_done");
}
} else {
bpf_program__set_attach_target(obj->progs.blk_account_io_start, 0,
"__blk_account_io_start");
bpf_program__set_attach_target(obj->progs.blk_account_io_done, 0,
"__blk_account_io_done");
bpf_program__set_autoload(obj->progs.blk_account_io_merge_bio, false);
bpf_program__set_autoload(obj->progs.blk_account_io_start, false);
bpf_program__set_autoload(obj->progs.blk_account_io_done, false);

if (!kprobe_exists("blk_account_io_merge_bio"))
bpf_program__set_autoload(obj->progs.kprobe_blk_account_io_merge_bio, false);
if (!kprobe_exists("blk_account_io_start")) {
bpf_program__set_autoload(obj->progs.kprobe_blk_account_io_start, false);
bpf_program__set_autoload(obj->progs.kprobe_blk_account_io_done, false);
} else {
bpf_program__set_autoload(obj->progs.kprobe___blk_account_io_start, false);
bpf_program__set_autoload(obj->progs.kprobe___blk_account_io_done, false);
}
}

err = biostacks_bpf__load(obj);
Expand All @@ -190,34 +212,17 @@ int main(int argc, char **argv)
goto cleanup;
}

obj->links.blk_account_io_start = bpf_program__attach(obj->progs.blk_account_io_start);
if (!obj->links.blk_account_io_start) {
err = -errno;
fprintf(stderr, "failed to attach blk_account_io_start: %s\n", strerror(-err));
err = biostacks_bpf__attach(obj);
if (err) {
fprintf(stderr, "failed to attach BPF programs\n");
goto cleanup;
}

ksyms = ksyms__load();
if (!ksyms) {
fprintf(stderr, "failed to load kallsyms\n");
goto cleanup;
}
if (ksyms__get_symbol(ksyms, "blk_account_io_merge_bio")) {
obj->links.blk_account_io_merge_bio =
bpf_program__attach(obj->progs.blk_account_io_merge_bio);
if (!obj->links.blk_account_io_merge_bio) {
err = -errno;
fprintf(stderr, "failed to attach blk_account_io_merge_bio: %s\n",
strerror(-err));
goto cleanup;
}
}
obj->links.blk_account_io_done = bpf_program__attach(obj->progs.blk_account_io_done);
if (!obj->links.blk_account_io_done) {
err = -errno;
fprintf(stderr, "failed to attach blk_account_io_done: %s\n",
strerror(-err));
goto cleanup;
}

signal(SIGINT, sig_handler);

Expand Down

0 comments on commit e54191e

Please sign in to comment.