Skip to content

Commit 2b2807d

Browse files
authored
Merge pull request #543 from niko-lay/cephfs-dist
Exporter to measure cephfs performance
2 parents af42843 + 58d5d31 commit 2b2807d

File tree

3 files changed

+167
-2
lines changed

3 files changed

+167
-2
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,16 @@ jobs:
501501
- name: Print kernel version
502502
run: uname -a
503503

504-
# Some programs expect to attach to symbols in modules
504+
- name: Install dependencies for ceph fs exporter
505+
run: |
506+
sudo apt update
507+
sudo apt install -y ceph-common
508+
509+
# Some programs expect to attach to symbols in modules
505510
- name: Load expected kernel modules
506-
run: sudo modprobe xfs
511+
run: |
512+
sudo modprobe xfs
513+
sudo modprobe ceph
507514
508515
- name: Run configuration check
509516
run: make config-check

examples/cephfs-dist.bpf.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#include <vmlinux.h>
2+
#include <bpf/bpf_helpers.h>
3+
#include "maps.bpf.h"
4+
5+
#define MAX_ENTRIES 10240
6+
7+
// 27 buckets for latency, max range is 33.6s .. 67.1s
8+
#define MAX_LATENCY_SLOT 27
9+
10+
enum fs_file_op {
11+
F_READ,
12+
F_WRITE,
13+
F_MKDIR,
14+
F_UNLINK,
15+
F_FSYNC,
16+
17+
F_MAX
18+
};
19+
20+
struct cephfs_latency_key_t {
21+
u8 op;
22+
u8 bucket;
23+
};
24+
25+
struct {
26+
__uint(type, BPF_MAP_TYPE_LRU_HASH);
27+
__uint(max_entries, MAX_ENTRIES);
28+
__type(key, u32);
29+
__type(value, u64);
30+
} start SEC(".maps");
31+
32+
struct {
33+
__uint(type, BPF_MAP_TYPE_HASH);
34+
__uint(max_entries, (MAX_LATENCY_SLOT + 1) * F_MAX);
35+
__type(key, struct cephfs_latency_key_t);
36+
__type(value, u64);
37+
} cephfs_latency_seconds SEC(".maps");
38+
39+
static int probe_entry()
40+
{
41+
u32 pid = bpf_get_current_pid_tgid();
42+
u64 ts = bpf_ktime_get_ns();
43+
44+
bpf_map_update_elem(&start, &pid, &ts, BPF_ANY);
45+
46+
return 0;
47+
}
48+
49+
static int probe_return(enum fs_file_op op)
50+
{
51+
u64 *tsp, delta_us, ts = bpf_ktime_get_ns();
52+
u32 pid = bpf_get_current_pid_tgid();
53+
struct cephfs_latency_key_t key = { .op = (u8) op };
54+
55+
tsp = bpf_map_lookup_elem(&start, &pid);
56+
if (!tsp) {
57+
return 0;
58+
}
59+
60+
delta_us = (ts - *tsp) / 1000;
61+
62+
increment_exp2_histogram(&cephfs_latency_seconds, key, delta_us, MAX_LATENCY_SLOT);
63+
64+
bpf_map_delete_elem(&start, &pid);
65+
66+
return 0;
67+
}
68+
69+
// kprobe:ceph_read_iter
70+
SEC("kprobe/ceph_read_iter")
71+
int cephfs_read_enter()
72+
{
73+
return probe_entry();
74+
}
75+
76+
SEC("kretprobe/ceph_read_iter")
77+
int cephfs_read_exit()
78+
{
79+
return probe_return(F_READ);
80+
}
81+
82+
// kprobe:ceph_write_iter
83+
SEC("kprobe/ceph_write_iter")
84+
int cephfs_write_enter()
85+
{
86+
return probe_entry();
87+
}
88+
89+
SEC("kretprobe/ceph_write_iter")
90+
int cephfs_write_exit()
91+
{
92+
return probe_return(F_WRITE);
93+
}
94+
95+
// kprobe:ceph_mkdir
96+
SEC("kprobe/ceph_mkdir")
97+
int cephfs_mkdir_enter()
98+
{
99+
return probe_entry();
100+
}
101+
102+
SEC("kretprobe/ceph_mkdir")
103+
int cephfs_mkdir_exit()
104+
{
105+
return probe_return(F_MKDIR);
106+
}
107+
108+
// kprobe:ceph_unlink
109+
SEC("kprobe/ceph_unlink")
110+
int cephfs_unlink_enter()
111+
{
112+
return probe_entry();
113+
}
114+
115+
SEC("kretprobe/ceph_unlink")
116+
int cephfs_unlink_exit()
117+
{
118+
return probe_return(F_UNLINK);
119+
}
120+
121+
// kprobe:ceph_fsync
122+
SEC("kprobe/ceph_fsync")
123+
int cephfs_fsync_enter()
124+
{
125+
return probe_entry();
126+
}
127+
128+
SEC("kretprobe/ceph_fsync")
129+
int cephfs_fsync_exit()
130+
{
131+
return probe_return(F_FSYNC);
132+
}
133+
134+
char LICENSE[] SEC("license") = "GPL";

examples/cephfs-dist.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
metrics:
2+
histograms:
3+
- name: cephfs_latency_seconds
4+
help: cephfs IO latency histogram
5+
bucket_type: exp2
6+
bucket_min: 0
7+
bucket_max: 27
8+
bucket_multiplier: 0.000001 # microseconds to seconds
9+
labels:
10+
- name: operation
11+
size: 1
12+
decoders:
13+
- name: uint
14+
- name: static_map
15+
static_map:
16+
0: read
17+
1: write
18+
2: mkdir
19+
3: unlink
20+
4: fsync
21+
- name: bucket
22+
size: 1
23+
decoders:
24+
- name: uint

0 commit comments

Comments
 (0)