Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / perf / util / bpf_skel / func_latency.bpf.c
blobf613dc9cb123480cf64493ec2b23f389415da3a9
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 // Copyright (c) 2021 Google
3 #include "vmlinux.h"
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_tracing.h>
7 // This should be in sync with "util/ftrace.h"
8 #define NUM_BUCKET 22
10 struct {
11 __uint(type, BPF_MAP_TYPE_HASH);
12 __uint(key_size, sizeof(__u64));
13 __uint(value_size, sizeof(__u64));
14 __uint(max_entries, 10000);
15 } functime SEC(".maps");
17 struct {
18 __uint(type, BPF_MAP_TYPE_HASH);
19 __uint(key_size, sizeof(__u32));
20 __uint(value_size, sizeof(__u8));
21 __uint(max_entries, 1);
22 } cpu_filter SEC(".maps");
24 struct {
25 __uint(type, BPF_MAP_TYPE_HASH);
26 __uint(key_size, sizeof(__u32));
27 __uint(value_size, sizeof(__u8));
28 __uint(max_entries, 1);
29 } task_filter SEC(".maps");
31 struct {
32 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
33 __uint(key_size, sizeof(__u32));
34 __uint(value_size, sizeof(__u64));
35 __uint(max_entries, NUM_BUCKET);
36 } latency SEC(".maps");
39 int enabled = 0;
41 const volatile int has_cpu = 0;
42 const volatile int has_task = 0;
43 const volatile int use_nsec = 0;
45 SEC("kprobe/func")
46 int BPF_PROG(func_begin)
48 __u64 key, now;
50 if (!enabled)
51 return 0;
53 key = bpf_get_current_pid_tgid();
55 if (has_cpu) {
56 __u32 cpu = bpf_get_smp_processor_id();
57 __u8 *ok;
59 ok = bpf_map_lookup_elem(&cpu_filter, &cpu);
60 if (!ok)
61 return 0;
64 if (has_task) {
65 __u32 pid = key & 0xffffffff;
66 __u8 *ok;
68 ok = bpf_map_lookup_elem(&task_filter, &pid);
69 if (!ok)
70 return 0;
73 now = bpf_ktime_get_ns();
75 // overwrite timestamp for nested functions
76 bpf_map_update_elem(&functime, &key, &now, BPF_ANY);
77 return 0;
80 SEC("kretprobe/func")
81 int BPF_PROG(func_end)
83 __u64 tid;
84 __u64 *start;
85 __u64 cmp_base = use_nsec ? 1 : 1000;
87 if (!enabled)
88 return 0;
90 tid = bpf_get_current_pid_tgid();
92 start = bpf_map_lookup_elem(&functime, &tid);
93 if (start) {
94 __s64 delta = bpf_ktime_get_ns() - *start;
95 __u32 key;
96 __u64 *hist;
98 bpf_map_delete_elem(&functime, &tid);
100 if (delta < 0)
101 return 0;
103 // calculate index using delta
104 for (key = 0; key < (NUM_BUCKET - 1); key++) {
105 if (delta < (cmp_base << key))
106 break;
109 hist = bpf_map_lookup_elem(&latency, &key);
110 if (!hist)
111 return 0;
113 *hist += 1;
116 return 0;