xref: /aosp_15_r20/external/bcc/libbpf-tools/fsdist.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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[F_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 	__u64 udelta;
45 
46 	tsp = bpf_map_lookup_elem(&starts, &tid);
47 	if (!tsp)
48 		return 0;
49 
50 	if (op >= F_MAX_OP)
51 		goto cleanup;
52 
53 	delta = (__s64)(ts - *tsp);
54 	if (delta < 0)
55 		goto cleanup;
56 
57 	udelta = (__u64)delta;
58 	if (in_ms)
59 		udelta /= 1000000;
60 	else
61 		udelta /= 1000;
62 
63 	slot = log2l(udelta);
64 	if (slot >= MAX_SLOTS)
65 		slot = MAX_SLOTS - 1;
66 	__sync_fetch_and_add(&hists[op].slots[slot], 1);
67 
68 cleanup:
69 	bpf_map_delete_elem(&starts, &tid);
70 	return 0;
71 }
72 
73 SEC("kprobe/dummy_file_read")
BPF_KPROBE(file_read_entry)74 int BPF_KPROBE(file_read_entry)
75 {
76 	return probe_entry();
77 }
78 
79 SEC("kretprobe/dummy_file_read")
BPF_KRETPROBE(file_read_exit)80 int BPF_KRETPROBE(file_read_exit)
81 {
82 	return probe_return(F_READ);
83 }
84 
85 SEC("kprobe/dummy_file_write")
BPF_KPROBE(file_write_entry)86 int BPF_KPROBE(file_write_entry)
87 {
88 	return probe_entry();
89 }
90 
91 SEC("kretprobe/dummy_file_write")
BPF_KRETPROBE(file_write_exit)92 int BPF_KRETPROBE(file_write_exit)
93 {
94 	return probe_return(F_WRITE);
95 }
96 
97 SEC("kprobe/dummy_file_open")
BPF_KPROBE(file_open_entry)98 int BPF_KPROBE(file_open_entry)
99 {
100 	return probe_entry();
101 }
102 
103 SEC("kretprobe/dummy_file_open")
BPF_KRETPROBE(file_open_exit)104 int BPF_KRETPROBE(file_open_exit)
105 {
106 	return probe_return(F_OPEN);
107 }
108 
109 SEC("kprobe/dummy_file_sync")
BPF_KPROBE(file_sync_entry)110 int BPF_KPROBE(file_sync_entry)
111 {
112 	return probe_entry();
113 }
114 
115 SEC("kretprobe/dummy_file_sync")
BPF_KRETPROBE(file_sync_exit)116 int BPF_KRETPROBE(file_sync_exit)
117 {
118 	return probe_return(F_FSYNC);
119 }
120 
121 SEC("kprobe/dummy_getattr")
BPF_KPROBE(getattr_entry)122 int BPF_KPROBE(getattr_entry)
123 {
124 	return probe_entry();
125 }
126 
127 SEC("kretprobe/dummy_getattr")
BPF_KRETPROBE(getattr_exit)128 int BPF_KRETPROBE(getattr_exit)
129 {
130 	return probe_return(F_GETATTR);
131 }
132 
133 SEC("fentry/dummy_file_read")
BPF_PROG(file_read_fentry)134 int BPF_PROG(file_read_fentry)
135 {
136 	return probe_entry();
137 }
138 
139 SEC("fexit/dummy_file_read")
BPF_PROG(file_read_fexit)140 int BPF_PROG(file_read_fexit)
141 {
142 	return probe_return(F_READ);
143 }
144 
145 SEC("fentry/dummy_file_write")
BPF_PROG(file_write_fentry)146 int BPF_PROG(file_write_fentry)
147 {
148 	return probe_entry();
149 }
150 
151 SEC("fexit/dummy_file_write")
BPF_PROG(file_write_fexit)152 int BPF_PROG(file_write_fexit)
153 {
154 	return probe_return(F_WRITE);
155 }
156 
157 SEC("fentry/dummy_file_open")
BPF_PROG(file_open_fentry)158 int BPF_PROG(file_open_fentry)
159 {
160 	return probe_entry();
161 }
162 
163 SEC("fexit/dummy_file_open")
BPF_PROG(file_open_fexit)164 int BPF_PROG(file_open_fexit)
165 {
166 	return probe_return(F_OPEN);
167 }
168 
169 SEC("fentry/dummy_file_sync")
BPF_PROG(file_sync_fentry)170 int BPF_PROG(file_sync_fentry)
171 {
172 	return probe_entry();
173 }
174 
175 SEC("fexit/dummy_file_sync")
BPF_PROG(file_sync_fexit)176 int BPF_PROG(file_sync_fexit)
177 {
178 	return probe_return(F_FSYNC);
179 }
180 
181 SEC("fentry/dummy_getattr")
BPF_PROG(getattr_fentry)182 int BPF_PROG(getattr_fentry)
183 {
184 	return probe_entry();
185 }
186 
187 SEC("fexit/dummy_getattr")
BPF_PROG(getattr_fexit)188 int BPF_PROG(getattr_fexit)
189 {
190 	return probe_return(F_GETATTR);
191 }
192 
193 char LICENSE[] SEC("license") = "Dual BSD/GPL";
194