xref: /aosp_15_r20/external/bcc/libbpf-tools/funclatency.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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