bcc/libbpf-tools: Use fentry for vfsstat
Use fentry like vfsstat.py when it is available.
Signed-off-by: Kenta Tada <Kenta.Tada@sony.com>
diff --git a/libbpf-tools/trace_helpers.c b/libbpf-tools/trace_helpers.c
index 9ea0bb8..04a7a0b 100644
--- a/libbpf-tools/trace_helpers.c
+++ b/libbpf-tools/trace_helpers.c
@@ -1099,3 +1099,22 @@
fclose(f);
return false;
}
+
+bool vmlinux_btf_exists(void)
+{
+ if (!access("/sys/kernel/btf/vmlinux", R_OK))
+ return true;
+ return false;
+}
+
+bool module_btf_exists(const char *mod)
+{
+ char sysfs_mod[80];
+
+ if (mod) {
+ snprintf(sysfs_mod, sizeof(sysfs_mod), "/sys/kernel/btf/%s", mod);
+ if (!access(sysfs_mod, R_OK))
+ return true;
+ }
+ return false;
+}
diff --git a/libbpf-tools/trace_helpers.h b/libbpf-tools/trace_helpers.h
index 90d07fe..019380a 100644
--- a/libbpf-tools/trace_helpers.h
+++ b/libbpf-tools/trace_helpers.h
@@ -92,4 +92,7 @@
*/
bool kprobe_exists(const char *name);
+bool vmlinux_btf_exists(void);
+bool module_btf_exists(const char *mod);
+
#endif /* __TRACE_HELPERS_H */
diff --git a/libbpf-tools/vfsstat.bpf.c b/libbpf-tools/vfsstat.bpf.c
index c9a710a..268f7d1 100644
--- a/libbpf-tools/vfsstat.bpf.c
+++ b/libbpf-tools/vfsstat.bpf.c
@@ -16,31 +16,61 @@
}
SEC("kprobe/vfs_read")
-int BPF_KPROBE(vfs_read)
+int BPF_KPROBE(kprobe_vfs_read)
{
return inc_stats(S_READ);
}
SEC("kprobe/vfs_write")
-int BPF_KPROBE(vfs_write)
+int BPF_KPROBE(kprobe_vfs_write)
{
return inc_stats(S_WRITE);
}
SEC("kprobe/vfs_fsync")
-int BPF_KPROBE(vfs_fsync)
+int BPF_KPROBE(kprobe_vfs_fsync)
{
return inc_stats(S_FSYNC);
}
SEC("kprobe/vfs_open")
-int BPF_KPROBE(vfs_open)
+int BPF_KPROBE(kprobe_vfs_open)
{
return inc_stats(S_OPEN);
}
SEC("kprobe/vfs_create")
-int BPF_KPROBE(vfs_create)
+int BPF_KPROBE(kprobe_vfs_create)
+{
+ return inc_stats(S_CREATE);
+}
+
+SEC("fentry/vfs_read")
+int BPF_PROG(fentry_vfs_read)
+{
+ return inc_stats(S_READ);
+}
+
+SEC("fentry/vfs_write")
+int BPF_PROG(fentry_vfs_write)
+{
+ return inc_stats(S_WRITE);
+}
+
+SEC("fentry/vfs_fsync")
+int BPF_PROG(fentry_vfs_fsync)
+{
+ return inc_stats(S_FSYNC);
+}
+
+SEC("fentry/vfs_open")
+int BPF_PROG(fentry_vfs_open)
+{
+ return inc_stats(S_OPEN);
+}
+
+SEC("fentry/vfs_create")
+int BPF_PROG(fentry_vfs_create)
{
return inc_stats(S_CREATE);
}
diff --git a/libbpf-tools/vfsstat.c b/libbpf-tools/vfsstat.c
index 0969af0..ec9f5ab 100644
--- a/libbpf-tools/vfsstat.c
+++ b/libbpf-tools/vfsstat.c
@@ -140,7 +140,7 @@
.doc = argp_program_doc,
.args_doc = args_doc,
};
- struct vfsstat_bpf *obj;
+ struct vfsstat_bpf *skel;
int err;
err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
@@ -156,13 +156,34 @@
return 1;
}
- obj = vfsstat_bpf__open_and_load();
- if (!obj) {
- fprintf(stderr, "failed to open and/or load BPF object\n");
+ skel = vfsstat_bpf__open();
+ if (!skel) {
+ fprintf(stderr, "failed to open BPF skelect\n");
return 1;
}
- err = vfsstat_bpf__attach(obj);
+ /* It fallbacks to kprobes when kernel does not support fentry. */
+ if (vmlinux_btf_exists() && fentry_exists("vfs_read", NULL)) {
+ bpf_program__set_autoload(skel->progs.kprobe_vfs_read, false);
+ bpf_program__set_autoload(skel->progs.kprobe_vfs_write, false);
+ bpf_program__set_autoload(skel->progs.kprobe_vfs_fsync, false);
+ bpf_program__set_autoload(skel->progs.kprobe_vfs_open, false);
+ bpf_program__set_autoload(skel->progs.kprobe_vfs_create, false);
+ } else {
+ bpf_program__set_autoload(skel->progs.fentry_vfs_read, false);
+ bpf_program__set_autoload(skel->progs.fentry_vfs_write, false);
+ bpf_program__set_autoload(skel->progs.fentry_vfs_fsync, false);
+ bpf_program__set_autoload(skel->progs.fentry_vfs_open, false);
+ bpf_program__set_autoload(skel->progs.fentry_vfs_create, false);
+ }
+
+ err = vfsstat_bpf__load(skel);
+ if (err) {
+ fprintf(stderr, "failed to load BPF skelect: %d\n", err);
+ goto cleanup;
+ }
+
+ err = vfsstat_bpf__attach(skel);
if (err) {
fprintf(stderr, "failed to attach BPF programs: %s\n",
strerror(-err));
@@ -172,11 +193,11 @@
print_header();
do {
sleep(env.interval);
- print_and_reset_stats(obj->bss->stats);
+ print_and_reset_stats(skel->bss->stats);
} while (!env.count || --env.count);
cleanup:
- vfsstat_bpf__destroy(obj);
+ vfsstat_bpf__destroy(skel);
return err != 0;
}