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 
28 static int timer_cb(void *map, int *key, struct timer *timer)
29 {
30 	return 0;
31 }
32 
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 
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")
60 int raw_tp_timer(void *ctx)
61 {
62 	timer_work();
63 
64 	return 0;
65 }
66 
67 SEC("?tp/syscalls/sys_enter_nanosleep")
68 int tp_timer(void *ctx)
69 {
70 	timer_work();
71 
72 	return 0;
73 }
74 
75 SEC("?kprobe/sys_nanosleep")
76 int kprobe_timer(void *ctx)
77 {
78 	timer_work();
79 
80 	return 0;
81 }
82 
83 SEC("?perf_event")
84 int perf_event_timer(void *ctx)
85 {
86 	timer_work();
87 
88 	return 0;
89 }
90 
91 SEC("?raw_tp/sys_enter")
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")
100 int tp_spin_lock(void *ctx)
101 {
102 	spin_lock_work();
103 
104 	return 0;
105 }
106 
107 SEC("?kprobe/sys_nanosleep")
108 int kprobe_spin_lock(void *ctx)
109 {
110 	spin_lock_work();
111 
112 	return 0;
113 }
114 
115 SEC("?perf_event")
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