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