• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2 /* Copyright (c) 2021 Hengqi Chen */
3 #include <vmlinux.h>
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_tracing.h>
6 #include "bits.bpf.h"
7 #include "fsdist.h"
8 
9 #define MAX_ENTRIES	10240
10 
11 const volatile pid_t target_pid = 0;
12 const volatile bool in_ms = false;
13 
14 struct {
15 	__uint(type, BPF_MAP_TYPE_HASH);
16 	__uint(max_entries, MAX_ENTRIES);
17 	__type(key, __u32);
18 	__type(value, __u64);
19 } starts SEC(".maps");
20 
21 struct hist hists[MAX_OP] = {};
22 
probe_entry()23 static int probe_entry()
24 {
25 	__u64 pid_tgid = bpf_get_current_pid_tgid();
26 	__u32 pid = pid_tgid >> 32;
27 	__u32 tid = (__u32)pid_tgid;
28 	__u64 ts;
29 
30 	if (target_pid && target_pid != pid)
31 		return 0;
32 
33 	ts = bpf_ktime_get_ns();
34 	bpf_map_update_elem(&starts, &tid, &ts, BPF_ANY);
35 	return 0;
36 }
37 
probe_return(enum fs_file_op op)38 static int probe_return(enum fs_file_op op)
39 {
40 	__u32 tid = (__u32)bpf_get_current_pid_tgid();
41 	__u64 ts = bpf_ktime_get_ns();
42 	__u64 *tsp, slot;
43 	__s64 delta;
44 
45 	tsp = bpf_map_lookup_elem(&starts, &tid);
46 	if (!tsp)
47 		return 0;
48 
49 	if (op >= MAX_OP)
50 		goto cleanup;
51 
52 	delta = (__s64)(ts - *tsp);
53 	if (delta < 0)
54 		goto cleanup;
55 
56 	if (in_ms)
57 		delta /= 1000000;
58 	else
59 		delta /= 1000;
60 
61 	slot = log2l(delta);
62 	if (slot >= MAX_SLOTS)
63 		slot = MAX_SLOTS - 1;
64 	__sync_fetch_and_add(&hists[op].slots[slot], 1);
65 
66 cleanup:
67 	bpf_map_delete_elem(&starts, &tid);
68 	return 0;
69 }
70 
71 SEC("kprobe/dummy_file_read")
BPF_KPROBE(file_read_entry)72 int BPF_KPROBE(file_read_entry)
73 {
74 	return probe_entry();
75 }
76 
77 SEC("kretprobe/dummy_file_read")
BPF_KRETPROBE(file_read_exit)78 int BPF_KRETPROBE(file_read_exit)
79 {
80 	return probe_return(READ);
81 }
82 
83 SEC("kprobe/dummy_file_write")
BPF_KPROBE(file_write_entry)84 int BPF_KPROBE(file_write_entry)
85 {
86 	return probe_entry();
87 }
88 
89 SEC("kretprobe/dummy_file_write")
BPF_KRETPROBE(file_write_exit)90 int BPF_KRETPROBE(file_write_exit)
91 {
92 	return probe_return(WRITE);
93 }
94 
95 SEC("kprobe/dummy_file_open")
BPF_KPROBE(file_open_entry)96 int BPF_KPROBE(file_open_entry)
97 {
98 	return probe_entry();
99 }
100 
101 SEC("kretprobe/dummy_file_open")
BPF_KRETPROBE(file_open_exit)102 int BPF_KRETPROBE(file_open_exit)
103 {
104 	return probe_return(OPEN);
105 }
106 
107 SEC("kprobe/dummy_file_sync")
BPF_KPROBE(file_sync_entry)108 int BPF_KPROBE(file_sync_entry)
109 {
110 	return probe_entry();
111 }
112 
113 SEC("kretprobe/dummy_file_sync")
BPF_KRETPROBE(file_sync_exit)114 int BPF_KRETPROBE(file_sync_exit)
115 {
116 	return probe_return(FSYNC);
117 }
118 
119 SEC("kprobe/dummy_getattr")
BPF_KPROBE(getattr_entry)120 int BPF_KPROBE(getattr_entry)
121 {
122 	return probe_entry();
123 }
124 
125 SEC("kretprobe/dummy_getattr")
BPF_KRETPROBE(getattr_exit)126 int BPF_KRETPROBE(getattr_exit)
127 {
128 	return probe_return(GETATTR);
129 }
130 
131 SEC("fentry/dummy_file_read")
BPF_PROG(file_read_fentry)132 int BPF_PROG(file_read_fentry)
133 {
134 	return probe_entry();
135 }
136 
137 SEC("fexit/dummy_file_read")
BPF_PROG(file_read_fexit)138 int BPF_PROG(file_read_fexit)
139 {
140 	return probe_return(READ);
141 }
142 
143 SEC("fentry/dummy_file_write")
BPF_PROG(file_write_fentry)144 int BPF_PROG(file_write_fentry)
145 {
146 	return probe_entry();
147 }
148 
149 SEC("fexit/dummy_file_write")
BPF_PROG(file_write_fexit)150 int BPF_PROG(file_write_fexit)
151 {
152 	return probe_return(WRITE);
153 }
154 
155 SEC("fentry/dummy_file_open")
BPF_PROG(file_open_fentry)156 int BPF_PROG(file_open_fentry)
157 {
158 	return probe_entry();
159 }
160 
161 SEC("fexit/dummy_file_open")
BPF_PROG(file_open_fexit)162 int BPF_PROG(file_open_fexit)
163 {
164 	return probe_return(OPEN);
165 }
166 
167 SEC("fentry/dummy_file_sync")
BPF_PROG(file_sync_fentry)168 int BPF_PROG(file_sync_fentry)
169 {
170 	return probe_entry();
171 }
172 
173 SEC("fexit/dummy_file_sync")
BPF_PROG(file_sync_fexit)174 int BPF_PROG(file_sync_fexit)
175 {
176 	return probe_return(FSYNC);
177 }
178 
179 SEC("fentry/dummy_getattr")
BPF_PROG(getattr_fentry)180 int BPF_PROG(getattr_fentry)
181 {
182 	return probe_entry();
183 }
184 
185 SEC("fexit/dummy_getattr")
BPF_PROG(getattr_fexit)186 int BPF_PROG(getattr_fexit)
187 {
188 	return probe_return(GETATTR);
189 }
190 
191 char LICENSE[] SEC("license") = "Dual BSD/GPL";
192