1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <time.h>
3 #include <linux/bpf.h>
4 #include <bpf/bpf_helpers.h>
5
6 struct timer {
7 struct bpf_timer t;
8 };
9
10 struct lock {
11 struct bpf_spin_lock l;
12 };
13
14 struct {
15 __uint(type, BPF_MAP_TYPE_ARRAY);
16 __uint(max_entries, 1);
17 __type(key, __u32);
18 __type(value, struct timer);
19 } timers SEC(".maps");
20
21 struct {
22 __uint(type, BPF_MAP_TYPE_ARRAY);
23 __uint(max_entries, 1);
24 __type(key, __u32);
25 __type(value, struct lock);
26 } locks SEC(".maps");
27
timer_cb(void * map,int * key,struct timer * timer)28 static int timer_cb(void *map, int *key, struct timer *timer)
29 {
30 return 0;
31 }
32
timer_work(void)33 static void timer_work(void)
34 {
35 struct timer *timer;
36 const int key = 0;
37
38 timer = bpf_map_lookup_elem(&timers, &key);
39 if (timer) {
40 bpf_timer_init(&timer->t, &timers, CLOCK_MONOTONIC);
41 bpf_timer_set_callback(&timer->t, timer_cb);
42 bpf_timer_start(&timer->t, 10E9, 0);
43 bpf_timer_cancel(&timer->t);
44 }
45 }
46
spin_lock_work(void)47 static void spin_lock_work(void)
48 {
49 const int key = 0;
50 struct lock *lock;
51
52 lock = bpf_map_lookup_elem(&locks, &key);
53 if (lock) {
54 bpf_spin_lock(&lock->l);
55 bpf_spin_unlock(&lock->l);
56 }
57 }
58
59 SEC("raw_tp/sys_enter")
raw_tp_timer(void * ctx)60 int raw_tp_timer(void *ctx)
61 {
62 timer_work();
63
64 return 0;
65 }
66
67 SEC("tp/syscalls/sys_enter_nanosleep")
tp_timer(void * ctx)68 int tp_timer(void *ctx)
69 {
70 timer_work();
71
72 return 0;
73 }
74
75 SEC("kprobe/sys_nanosleep")
kprobe_timer(void * ctx)76 int kprobe_timer(void *ctx)
77 {
78 timer_work();
79
80 return 0;
81 }
82
83 SEC("perf_event")
perf_event_timer(void * ctx)84 int perf_event_timer(void *ctx)
85 {
86 timer_work();
87
88 return 0;
89 }
90
91 SEC("raw_tp/sys_enter")
raw_tp_spin_lock(void * ctx)92 int raw_tp_spin_lock(void *ctx)
93 {
94 spin_lock_work();
95
96 return 0;
97 }
98
99 SEC("tp/syscalls/sys_enter_nanosleep")
tp_spin_lock(void * ctx)100 int tp_spin_lock(void *ctx)
101 {
102 spin_lock_work();
103
104 return 0;
105 }
106
107 SEC("kprobe/sys_nanosleep")
kprobe_spin_lock(void * ctx)108 int kprobe_spin_lock(void *ctx)
109 {
110 spin_lock_work();
111
112 return 0;
113 }
114
115 SEC("perf_event")
perf_event_spin_lock(void * ctx)116 int perf_event_spin_lock(void *ctx)
117 {
118 spin_lock_work();
119
120 return 0;
121 }
122
123 const char LICENSE[] SEC("license") = "GPL";
124