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_tracing.h>
6*387f9dfdSAndroid Build Coastguard Worker #include "readahead.h"
7*387f9dfdSAndroid Build Coastguard Worker #include "bits.bpf.h"
8*387f9dfdSAndroid Build Coastguard Worker
9*387f9dfdSAndroid Build Coastguard Worker #define MAX_ENTRIES 10240
10*387f9dfdSAndroid Build Coastguard Worker
11*387f9dfdSAndroid Build Coastguard Worker struct {
12*387f9dfdSAndroid Build Coastguard Worker __uint(type, BPF_MAP_TYPE_HASH);
13*387f9dfdSAndroid Build Coastguard Worker __uint(max_entries, MAX_ENTRIES);
14*387f9dfdSAndroid Build Coastguard Worker __type(key, u32);
15*387f9dfdSAndroid Build Coastguard Worker __type(value, u64);
16*387f9dfdSAndroid Build Coastguard Worker } in_readahead SEC(".maps");
17*387f9dfdSAndroid Build Coastguard Worker
18*387f9dfdSAndroid Build Coastguard Worker struct {
19*387f9dfdSAndroid Build Coastguard Worker __uint(type, BPF_MAP_TYPE_HASH);
20*387f9dfdSAndroid Build Coastguard Worker __uint(max_entries, MAX_ENTRIES);
21*387f9dfdSAndroid Build Coastguard Worker __type(key, struct page *);
22*387f9dfdSAndroid Build Coastguard Worker __type(value, u64);
23*387f9dfdSAndroid Build Coastguard Worker } birth SEC(".maps");
24*387f9dfdSAndroid Build Coastguard Worker
25*387f9dfdSAndroid Build Coastguard Worker struct hist hist = {};
26*387f9dfdSAndroid Build Coastguard Worker
27*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/do_page_cache_ra")
BPF_PROG(do_page_cache_ra)28*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(do_page_cache_ra)
29*387f9dfdSAndroid Build Coastguard Worker {
30*387f9dfdSAndroid Build Coastguard Worker u32 pid = bpf_get_current_pid_tgid();
31*387f9dfdSAndroid Build Coastguard Worker u64 one = 1;
32*387f9dfdSAndroid Build Coastguard Worker
33*387f9dfdSAndroid Build Coastguard Worker bpf_map_update_elem(&in_readahead, &pid, &one, 0);
34*387f9dfdSAndroid Build Coastguard Worker return 0;
35*387f9dfdSAndroid Build Coastguard Worker }
36*387f9dfdSAndroid Build Coastguard Worker
37*387f9dfdSAndroid Build Coastguard Worker SEC("fexit/__page_cache_alloc")
BPF_PROG(page_cache_alloc_ret,gfp_t gfp,struct page * ret)38*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(page_cache_alloc_ret, gfp_t gfp, struct page *ret)
39*387f9dfdSAndroid Build Coastguard Worker {
40*387f9dfdSAndroid Build Coastguard Worker u32 pid = bpf_get_current_pid_tgid();
41*387f9dfdSAndroid Build Coastguard Worker u64 ts;
42*387f9dfdSAndroid Build Coastguard Worker
43*387f9dfdSAndroid Build Coastguard Worker if (!bpf_map_lookup_elem(&in_readahead, &pid))
44*387f9dfdSAndroid Build Coastguard Worker return 0;
45*387f9dfdSAndroid Build Coastguard Worker
46*387f9dfdSAndroid Build Coastguard Worker ts = bpf_ktime_get_ns();
47*387f9dfdSAndroid Build Coastguard Worker bpf_map_update_elem(&birth, &ret, &ts, 0);
48*387f9dfdSAndroid Build Coastguard Worker __sync_fetch_and_add(&hist.unused, 1);
49*387f9dfdSAndroid Build Coastguard Worker __sync_fetch_and_add(&hist.total, 1);
50*387f9dfdSAndroid Build Coastguard Worker
51*387f9dfdSAndroid Build Coastguard Worker return 0;
52*387f9dfdSAndroid Build Coastguard Worker }
53*387f9dfdSAndroid Build Coastguard Worker
54*387f9dfdSAndroid Build Coastguard Worker SEC("fexit/do_page_cache_ra")
BPF_PROG(do_page_cache_ra_ret)55*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(do_page_cache_ra_ret)
56*387f9dfdSAndroid Build Coastguard Worker {
57*387f9dfdSAndroid Build Coastguard Worker u32 pid = bpf_get_current_pid_tgid();
58*387f9dfdSAndroid Build Coastguard Worker
59*387f9dfdSAndroid Build Coastguard Worker bpf_map_delete_elem(&in_readahead, &pid);
60*387f9dfdSAndroid Build Coastguard Worker return 0;
61*387f9dfdSAndroid Build Coastguard Worker }
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker SEC("fentry/mark_page_accessed")
BPF_PROG(mark_page_accessed,struct page * page)64*387f9dfdSAndroid Build Coastguard Worker int BPF_PROG(mark_page_accessed, struct page *page)
65*387f9dfdSAndroid Build Coastguard Worker {
66*387f9dfdSAndroid Build Coastguard Worker u64 *tsp, slot, ts = bpf_ktime_get_ns();
67*387f9dfdSAndroid Build Coastguard Worker s64 delta;
68*387f9dfdSAndroid Build Coastguard Worker
69*387f9dfdSAndroid Build Coastguard Worker tsp = bpf_map_lookup_elem(&birth, &page);
70*387f9dfdSAndroid Build Coastguard Worker if (!tsp)
71*387f9dfdSAndroid Build Coastguard Worker return 0;
72*387f9dfdSAndroid Build Coastguard Worker delta = (s64)(ts - *tsp);
73*387f9dfdSAndroid Build Coastguard Worker if (delta < 0)
74*387f9dfdSAndroid Build Coastguard Worker goto update_and_cleanup;
75*387f9dfdSAndroid Build Coastguard Worker slot = log2l(delta / 1000000U);
76*387f9dfdSAndroid Build Coastguard Worker if (slot >= MAX_SLOTS)
77*387f9dfdSAndroid Build Coastguard Worker slot = MAX_SLOTS - 1;
78*387f9dfdSAndroid Build Coastguard Worker __sync_fetch_and_add(&hist.slots[slot], 1);
79*387f9dfdSAndroid Build Coastguard Worker
80*387f9dfdSAndroid Build Coastguard Worker update_and_cleanup:
81*387f9dfdSAndroid Build Coastguard Worker __sync_fetch_and_add(&hist.unused, -1);
82*387f9dfdSAndroid Build Coastguard Worker bpf_map_delete_elem(&birth, &page);
83*387f9dfdSAndroid Build Coastguard Worker
84*387f9dfdSAndroid Build Coastguard Worker return 0;
85*387f9dfdSAndroid Build Coastguard Worker }
86*387f9dfdSAndroid Build Coastguard Worker
87*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
88