forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fsdist is a multitool which show filesystem latency. Currently we support btrfs/ext4/nfs/xfs filesystems. It behaves the same as its counterpart in BCC tools named btrfsdist.py/ext4dist.py/nfsdist.py/xfsdist.py Signed-off-by: Hengqi Chen <[email protected]>
- Loading branch information
1 parent
f2bb8f1
commit 5a69ec3
Showing
5 changed files
with
668 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
/execsnoop | ||
/ext4dist | ||
/filelife | ||
/fsdist | ||
/funclatency | ||
/gethostlatency | ||
/hardirqs | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ APPS = \ | |
execsnoop \ | ||
ext4dist \ | ||
filelife \ | ||
fsdist \ | ||
funclatency \ | ||
gethostlatency \ | ||
hardirqs \ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/* 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) | ||
{ | ||
__u64 pid_tgid = bpf_get_current_pid_tgid(); | ||
__u32 pid = pid_tgid >> 32; | ||
__u32 tid = (__u32)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"; |
Oops, something went wrong.