/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ /* Copyright (c) 2021 Hengqi Chen */ #include #include #include #include "bits.bpf.h" #include "fsdist.h" #define MAX_ENTRIES 10240 const volatile pid_t target_pid = 0; const volatile bool in_ms = false; struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, MAX_ENTRIES); __type(key, __u32); __type(value, __u64); } starts SEC(".maps"); struct hist hists[MAX_OP] = {}; static int probe_entry() { __u64 pid_tgid = bpf_get_current_pid_tgid(); __u32 pid = pid_tgid >> 32; __u32 tid = (__u32)pid_tgid; __u64 ts; if (target_pid && target_pid != pid) return 0; ts = bpf_ktime_get_ns(); bpf_map_update_elem(&starts, &tid, &ts, BPF_ANY); return 0; } static int probe_return(enum fs_file_op op) { __u32 tid = (__u32)bpf_get_current_pid_tgid(); __u64 ts = bpf_ktime_get_ns(); __u64 *tsp, slot; __s64 delta; tsp = bpf_map_lookup_elem(&starts, &tid); if (!tsp) return 0; if (op >= MAX_OP) goto cleanup; delta = (__s64)(ts - *tsp); if (delta < 0) goto cleanup; if (in_ms) delta /= 1000000; else delta /= 1000; slot = log2l(delta); if (slot >= MAX_SLOTS) slot = MAX_SLOTS - 1; __sync_fetch_and_add(&hists[op].slots[slot], 1); cleanup: bpf_map_delete_elem(&starts, &tid); return 0; } SEC("kprobe/dummy_file_read") int BPF_KPROBE(file_read_entry) { return probe_entry(); } SEC("kretprobe/dummy_file_read") int BPF_KRETPROBE(file_read_exit) { return probe_return(READ); } SEC("kprobe/dummy_file_write") int BPF_KPROBE(file_write_entry) { return probe_entry(); } SEC("kretprobe/dummy_file_write") int BPF_KRETPROBE(file_write_exit) { return probe_return(WRITE); } SEC("kprobe/dummy_file_open") int BPF_KPROBE(file_open_entry) { return probe_entry(); } SEC("kretprobe/dummy_file_open") int BPF_KRETPROBE(file_open_exit) { return probe_return(OPEN); } SEC("kprobe/dummy_file_sync") int BPF_KPROBE(file_sync_entry) { return probe_entry(); } SEC("kretprobe/dummy_file_sync") int BPF_KRETPROBE(file_sync_exit) { return probe_return(FSYNC); } SEC("kprobe/dummy_getattr") int BPF_KPROBE(getattr_entry) { return probe_entry(); } SEC("kretprobe/dummy_getattr") int BPF_KRETPROBE(getattr_exit) { return probe_return(GETATTR); } SEC("fentry/dummy_file_read") int BPF_PROG(file_read_fentry) { return probe_entry(); } SEC("fexit/dummy_file_read") int BPF_PROG(file_read_fexit) { return probe_return(READ); } SEC("fentry/dummy_file_write") int BPF_PROG(file_write_fentry) { return probe_entry(); } SEC("fexit/dummy_file_write") int BPF_PROG(file_write_fexit) { return probe_return(WRITE); } SEC("fentry/dummy_file_open") int BPF_PROG(file_open_fentry) { return probe_entry(); } SEC("fexit/dummy_file_open") int BPF_PROG(file_open_fexit) { return probe_return(OPEN); } SEC("fentry/dummy_file_sync") int BPF_PROG(file_sync_fentry) { return probe_entry(); } SEC("fexit/dummy_file_sync") int BPF_PROG(file_sync_fexit) { return probe_return(FSYNC); } SEC("fentry/dummy_getattr") int BPF_PROG(getattr_fentry) { return probe_entry(); } SEC("fexit/dummy_getattr") int BPF_PROG(getattr_fexit) { return probe_return(GETATTR); } char LICENSE[] SEC("license") = "Dual BSD/GPL";