192 lines
3.2 KiB
C
192 lines
3.2 KiB
C
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
|
/* Copyright (c) 2021 Hengqi Chen */
|
|
#include <vmlinux.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#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";
|