xref: /aosp_15_r20/external/bcc/libbpf-tools/fsslower.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0 */
2*387f9dfdSAndroid Build Coastguard Worker /* Copyright (c) 2020 Wenbo Zhang */
3*387f9dfdSAndroid Build Coastguard Worker #include <vmlinux.h>
4*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_helpers.h>
5*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_core_read.h>
6*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_tracing.h>
7*387f9dfdSAndroid Build Coastguard Worker #include "bits.bpf.h"
8*387f9dfdSAndroid Build Coastguard Worker #include "fsslower.h"
9*387f9dfdSAndroid Build Coastguard Worker 
10*387f9dfdSAndroid Build Coastguard Worker #define MAX_ENTRIES	8192
11*387f9dfdSAndroid Build Coastguard Worker 
12*387f9dfdSAndroid Build Coastguard Worker const volatile pid_t target_pid = 0;
13*387f9dfdSAndroid Build Coastguard Worker const volatile __u64 min_lat_ns = 0;
14*387f9dfdSAndroid Build Coastguard Worker 
15*387f9dfdSAndroid Build Coastguard Worker struct data {
16*387f9dfdSAndroid Build Coastguard Worker 	__u64 ts;
17*387f9dfdSAndroid Build Coastguard Worker 	loff_t start;
18*387f9dfdSAndroid Build Coastguard Worker 	loff_t end;
19*387f9dfdSAndroid Build Coastguard Worker 	struct file *fp;
20*387f9dfdSAndroid Build Coastguard Worker };
21*387f9dfdSAndroid Build Coastguard Worker 
22*387f9dfdSAndroid Build Coastguard Worker struct {
23*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_HASH);
24*387f9dfdSAndroid Build Coastguard Worker 	__uint(max_entries, MAX_ENTRIES);
25*387f9dfdSAndroid Build Coastguard Worker 	__type(key, __u32);
26*387f9dfdSAndroid Build Coastguard Worker 	__type(value, struct data);
27*387f9dfdSAndroid Build Coastguard Worker } starts SEC(".maps");
28*387f9dfdSAndroid Build Coastguard Worker 
29*387f9dfdSAndroid Build Coastguard Worker struct {
30*387f9dfdSAndroid Build Coastguard Worker 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
31*387f9dfdSAndroid Build Coastguard Worker 	__uint(key_size, sizeof(__u32));
32*387f9dfdSAndroid Build Coastguard Worker 	__uint(value_size, sizeof(__u32));
33*387f9dfdSAndroid Build Coastguard Worker } events SEC(".maps");
34*387f9dfdSAndroid Build Coastguard Worker 
probe_entry(struct file * fp,loff_t start,loff_t end)35*387f9dfdSAndroid Build Coastguard Worker static int probe_entry(struct file *fp, loff_t start, loff_t end)
36*387f9dfdSAndroid Build Coastguard Worker {
37*387f9dfdSAndroid Build Coastguard Worker 	__u64 pid_tgid = bpf_get_current_pid_tgid();
38*387f9dfdSAndroid Build Coastguard Worker 	__u32 pid = pid_tgid >> 32;
39*387f9dfdSAndroid Build Coastguard Worker 	__u32 tid = (__u32)pid_tgid;
40*387f9dfdSAndroid Build Coastguard Worker 	struct data data;
41*387f9dfdSAndroid Build Coastguard Worker 
42*387f9dfdSAndroid Build Coastguard Worker 	if (!fp)
43*387f9dfdSAndroid Build Coastguard Worker 		return 0;
44*387f9dfdSAndroid Build Coastguard Worker 
45*387f9dfdSAndroid Build Coastguard Worker 	if (target_pid && target_pid != pid)
46*387f9dfdSAndroid Build Coastguard Worker 		return 0;
47*387f9dfdSAndroid Build Coastguard Worker 
48*387f9dfdSAndroid Build Coastguard Worker 	data.ts = bpf_ktime_get_ns();
49*387f9dfdSAndroid Build Coastguard Worker 	data.start = start;
50*387f9dfdSAndroid Build Coastguard Worker 	data.end = end;
51*387f9dfdSAndroid Build Coastguard Worker 	data.fp = fp;
52*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_update_elem(&starts, &tid, &data, BPF_ANY);
53*387f9dfdSAndroid Build Coastguard Worker 	return 0;
54*387f9dfdSAndroid Build Coastguard Worker }
55*387f9dfdSAndroid Build Coastguard Worker 
probe_exit(void * ctx,enum fs_file_op op,ssize_t size)56*387f9dfdSAndroid Build Coastguard Worker static int probe_exit(void *ctx, enum fs_file_op op, ssize_t size)
57*387f9dfdSAndroid Build Coastguard Worker {
58*387f9dfdSAndroid Build Coastguard Worker 	__u64 pid_tgid = bpf_get_current_pid_tgid();
59*387f9dfdSAndroid Build Coastguard Worker 	__u32 pid = pid_tgid >> 32;
60*387f9dfdSAndroid Build Coastguard Worker 	__u32 tid = (__u32)pid_tgid;
61*387f9dfdSAndroid Build Coastguard Worker 	__u64 end_ns, delta_ns;
62*387f9dfdSAndroid Build Coastguard Worker 	const __u8 *file_name;
63*387f9dfdSAndroid Build Coastguard Worker 	struct data *datap;
64*387f9dfdSAndroid Build Coastguard Worker 	struct event event = {};
65*387f9dfdSAndroid Build Coastguard Worker 	struct dentry *dentry;
66*387f9dfdSAndroid Build Coastguard Worker 	struct file *fp;
67*387f9dfdSAndroid Build Coastguard Worker 
68*387f9dfdSAndroid Build Coastguard Worker 	if (target_pid && target_pid != pid)
69*387f9dfdSAndroid Build Coastguard Worker 		return 0;
70*387f9dfdSAndroid Build Coastguard Worker 
71*387f9dfdSAndroid Build Coastguard Worker 	datap = bpf_map_lookup_elem(&starts, &tid);
72*387f9dfdSAndroid Build Coastguard Worker 	if (!datap)
73*387f9dfdSAndroid Build Coastguard Worker 		return 0;
74*387f9dfdSAndroid Build Coastguard Worker 
75*387f9dfdSAndroid Build Coastguard Worker 	bpf_map_delete_elem(&starts, &tid);
76*387f9dfdSAndroid Build Coastguard Worker 
77*387f9dfdSAndroid Build Coastguard Worker 	end_ns = bpf_ktime_get_ns();
78*387f9dfdSAndroid Build Coastguard Worker 	delta_ns = end_ns - datap->ts;
79*387f9dfdSAndroid Build Coastguard Worker 	if (delta_ns <= min_lat_ns)
80*387f9dfdSAndroid Build Coastguard Worker 		return 0;
81*387f9dfdSAndroid Build Coastguard Worker 
82*387f9dfdSAndroid Build Coastguard Worker 	event.delta_us = delta_ns / 1000;
83*387f9dfdSAndroid Build Coastguard Worker 	event.end_ns = end_ns;
84*387f9dfdSAndroid Build Coastguard Worker 	event.offset = datap->start;
85*387f9dfdSAndroid Build Coastguard Worker 	if (op != F_FSYNC)
86*387f9dfdSAndroid Build Coastguard Worker 		event.size = size;
87*387f9dfdSAndroid Build Coastguard Worker 	else
88*387f9dfdSAndroid Build Coastguard Worker 		event.size = datap->end - datap->start;
89*387f9dfdSAndroid Build Coastguard Worker 	event.pid = pid;
90*387f9dfdSAndroid Build Coastguard Worker 	event.op = op;
91*387f9dfdSAndroid Build Coastguard Worker 	fp = datap->fp;
92*387f9dfdSAndroid Build Coastguard Worker 	dentry = BPF_CORE_READ(fp, f_path.dentry);
93*387f9dfdSAndroid Build Coastguard Worker 	file_name = BPF_CORE_READ(dentry, d_name.name);
94*387f9dfdSAndroid Build Coastguard Worker 	bpf_probe_read_kernel_str(&event.file, sizeof(event.file), file_name);
95*387f9dfdSAndroid Build Coastguard Worker 	bpf_get_current_comm(&event.task, sizeof(event.task));
96*387f9dfdSAndroid Build Coastguard Worker 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
97*387f9dfdSAndroid Build Coastguard Worker 	return 0;
98*387f9dfdSAndroid Build Coastguard Worker }
99*387f9dfdSAndroid Build Coastguard Worker 
100*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/dummy_file_read")
BPF_KPROBE(file_read_entry,struct kiocb * iocb)101*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(file_read_entry, struct kiocb *iocb)
102*387f9dfdSAndroid Build Coastguard Worker {
103*387f9dfdSAndroid Build Coastguard Worker 	struct file *fp = BPF_CORE_READ(iocb, ki_filp);
104*387f9dfdSAndroid Build Coastguard Worker 	loff_t start = BPF_CORE_READ(iocb, ki_pos);
105*387f9dfdSAndroid Build Coastguard Worker 
106*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(fp, start, 0);
107*387f9dfdSAndroid Build Coastguard Worker }
108*387f9dfdSAndroid Build Coastguard Worker 
109*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/dummy_file_read")
BPF_KRETPROBE(file_read_exit,ssize_t ret)110*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(file_read_exit, ssize_t ret)
111*387f9dfdSAndroid Build Coastguard Worker {
112*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_READ, ret);
113*387f9dfdSAndroid Build Coastguard Worker }
114*387f9dfdSAndroid Build Coastguard Worker 
115*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/dummy_file_write")
BPF_KPROBE(file_write_entry,struct kiocb * iocb)116*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(file_write_entry, struct kiocb *iocb)
117*387f9dfdSAndroid Build Coastguard Worker {
118*387f9dfdSAndroid Build Coastguard Worker 	struct file *fp = BPF_CORE_READ(iocb, ki_filp);
119*387f9dfdSAndroid Build Coastguard Worker 	loff_t start = BPF_CORE_READ(iocb, ki_pos);
120*387f9dfdSAndroid Build Coastguard Worker 
121*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(fp, start, 0);
122*387f9dfdSAndroid Build Coastguard Worker }
123*387f9dfdSAndroid Build Coastguard Worker 
124*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/dummy_file_write")
BPF_KRETPROBE(file_write_exit,ssize_t ret)125*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(file_write_exit, ssize_t ret)
126*387f9dfdSAndroid Build Coastguard Worker {
127*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_WRITE, ret);
128*387f9dfdSAndroid Build Coastguard Worker }
129*387f9dfdSAndroid Build Coastguard Worker 
130*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/dummy_file_open")
BPF_KPROBE(file_open_entry,struct inode * inode,struct file * file)131*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(file_open_entry, struct inode *inode, struct file *file)
132*387f9dfdSAndroid Build Coastguard Worker {
133*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(file, 0, 0);
134*387f9dfdSAndroid Build Coastguard Worker }
135*387f9dfdSAndroid Build Coastguard Worker 
136*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/dummy_file_open")
BPF_KRETPROBE(file_open_exit)137*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(file_open_exit)
138*387f9dfdSAndroid Build Coastguard Worker {
139*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_OPEN, 0);
140*387f9dfdSAndroid Build Coastguard Worker }
141*387f9dfdSAndroid Build Coastguard Worker 
142*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/dummy_file_sync")
BPF_KPROBE(file_sync_entry,struct file * file,loff_t start,loff_t end)143*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(file_sync_entry, struct file *file, loff_t start, loff_t end)
144*387f9dfdSAndroid Build Coastguard Worker {
145*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(file, start, end);
146*387f9dfdSAndroid Build Coastguard Worker }
147*387f9dfdSAndroid Build Coastguard Worker 
148*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/dummy_file_sync")
BPF_KRETPROBE(file_sync_exit)149*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(file_sync_exit)
150*387f9dfdSAndroid Build Coastguard Worker {
151*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_FSYNC, 0);
152*387f9dfdSAndroid Build Coastguard Worker }
153*387f9dfdSAndroid Build Coastguard Worker 
154*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/dummy_file_read")
BPF_PROG(file_read_fentry,struct kiocb * iocb)155*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_read_fentry, struct kiocb *iocb)
156*387f9dfdSAndroid Build Coastguard Worker {
157*387f9dfdSAndroid Build Coastguard Worker 	struct file *fp = iocb->ki_filp;
158*387f9dfdSAndroid Build Coastguard Worker 	loff_t start = iocb->ki_pos;
159*387f9dfdSAndroid Build Coastguard Worker 
160*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(fp, start, 0);
161*387f9dfdSAndroid Build Coastguard Worker }
162*387f9dfdSAndroid Build Coastguard Worker 
163*387f9dfdSAndroid Build Coastguard Worker SEC("fexit/dummy_file_read")
BPF_PROG(file_read_fexit,struct kiocb * iocb,struct iov_iter * to,ssize_t ret)164*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_read_fexit, struct kiocb *iocb, struct iov_iter *to, ssize_t ret)
165*387f9dfdSAndroid Build Coastguard Worker {
166*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_READ, ret);
167*387f9dfdSAndroid Build Coastguard Worker }
168*387f9dfdSAndroid Build Coastguard Worker 
169*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/dummy_file_write")
BPF_PROG(file_write_fentry,struct kiocb * iocb)170*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_write_fentry, struct kiocb *iocb)
171*387f9dfdSAndroid Build Coastguard Worker {
172*387f9dfdSAndroid Build Coastguard Worker 	struct file *fp = iocb->ki_filp;
173*387f9dfdSAndroid Build Coastguard Worker 	loff_t start = iocb->ki_pos;
174*387f9dfdSAndroid Build Coastguard Worker 
175*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(fp, start, 0);
176*387f9dfdSAndroid Build Coastguard Worker }
177*387f9dfdSAndroid Build Coastguard Worker 
178*387f9dfdSAndroid Build Coastguard Worker SEC("fexit/dummy_file_write")
BPF_PROG(file_write_fexit,struct kiocb * iocb,struct iov_iter * from,ssize_t ret)179*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_write_fexit, struct kiocb *iocb, struct iov_iter *from, ssize_t ret)
180*387f9dfdSAndroid Build Coastguard Worker {
181*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_WRITE, ret);
182*387f9dfdSAndroid Build Coastguard Worker }
183*387f9dfdSAndroid Build Coastguard Worker 
184*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/dummy_file_open")
BPF_PROG(file_open_fentry,struct inode * inode,struct file * file)185*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_open_fentry, struct inode *inode, struct file *file)
186*387f9dfdSAndroid Build Coastguard Worker {
187*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(file, 0, 0);
188*387f9dfdSAndroid Build Coastguard Worker }
189*387f9dfdSAndroid Build Coastguard Worker 
190*387f9dfdSAndroid Build Coastguard Worker SEC("fexit/dummy_file_open")
BPF_PROG(file_open_fexit)191*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_open_fexit)
192*387f9dfdSAndroid Build Coastguard Worker {
193*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_OPEN, 0);
194*387f9dfdSAndroid Build Coastguard Worker }
195*387f9dfdSAndroid Build Coastguard Worker 
196*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/dummy_file_sync")
BPF_PROG(file_sync_fentry,struct file * file,loff_t start,loff_t end)197*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_sync_fentry, struct file *file, loff_t start, loff_t end)
198*387f9dfdSAndroid Build Coastguard Worker {
199*387f9dfdSAndroid Build Coastguard Worker 	return probe_entry(file, start, end);
200*387f9dfdSAndroid Build Coastguard Worker }
201*387f9dfdSAndroid Build Coastguard Worker 
202*387f9dfdSAndroid Build Coastguard Worker SEC("fexit/dummy_file_sync")
BPF_PROG(file_sync_fexit)203*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(file_sync_fexit)
204*387f9dfdSAndroid Build Coastguard Worker {
205*387f9dfdSAndroid Build Coastguard Worker 	return probe_exit(ctx, F_FSYNC, 0);
206*387f9dfdSAndroid Build Coastguard Worker }
207*387f9dfdSAndroid Build Coastguard Worker 
208*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
209