1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2021 Google LLC. */
3 #include "vmlinux.h"
4 #include <bpf/bpf_core_read.h>
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
7 #include "funclatency.h"
8 #include "bits.bpf.h"
9
10 const volatile pid_t targ_tgid = 0;
11 const volatile int units = 0;
12 const volatile bool filter_cg = false;
13
14 struct {
15 __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
16 __type(key, u32);
17 __type(value, u32);
18 __uint(max_entries, 1);
19 } cgroup_map SEC(".maps");
20
21 /* key: pid. value: start time */
22 struct {
23 __uint(type, BPF_MAP_TYPE_HASH);
24 __uint(max_entries, MAX_PIDS);
25 __type(key, u32);
26 __type(value, u64);
27 } starts SEC(".maps");
28
29 __u32 hist[MAX_SLOTS] = {};
30
entry(void)31 static void entry(void)
32 {
33 u64 id = bpf_get_current_pid_tgid();
34 u32 tgid = id >> 32;
35 u32 pid = id;
36 u64 nsec;
37
38 if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
39 return;
40
41 if (targ_tgid && targ_tgid != tgid)
42 return;
43 nsec = bpf_ktime_get_ns();
44 bpf_map_update_elem(&starts, &pid, &nsec, BPF_ANY);
45 }
46
47 SEC("fentry/dummy_fentry")
BPF_PROG(dummy_fentry)48 int BPF_PROG(dummy_fentry)
49 {
50 entry();
51 return 0;
52 }
53
54 SEC("kprobe/dummy_kprobe")
BPF_KPROBE(dummy_kprobe)55 int BPF_KPROBE(dummy_kprobe)
56 {
57 entry();
58 return 0;
59 }
60
exit(void)61 static void exit(void)
62 {
63 u64 *start;
64 u64 nsec = bpf_ktime_get_ns();
65 u64 id = bpf_get_current_pid_tgid();
66 u32 pid = id;
67 u64 slot, delta;
68
69 if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
70 return;
71
72 start = bpf_map_lookup_elem(&starts, &pid);
73 if (!start)
74 return;
75
76 delta = nsec - *start;
77
78 switch (units) {
79 case USEC:
80 delta /= 1000;
81 break;
82 case MSEC:
83 delta /= 1000000;
84 break;
85 }
86
87 slot = log2l(delta);
88 if (slot >= MAX_SLOTS)
89 slot = MAX_SLOTS - 1;
90 __sync_fetch_and_add(&hist[slot], 1);
91 }
92
93 SEC("fexit/dummy_fexit")
BPF_PROG(dummy_fexit)94 int BPF_PROG(dummy_fexit)
95 {
96 exit();
97 return 0;
98 }
99
100 SEC("kretprobe/dummy_kretprobe")
BPF_KRETPROBE(dummy_kretprobe)101 int BPF_KRETPROBE(dummy_kretprobe)
102 {
103 exit();
104 return 0;
105 }
106
107 char LICENSE[] SEC("license") = "GPL";
108