1// SPDX-License-Identifier: GPL-2.0-only
2#include <time.h>
3#include <linux/bpf.h>
4#include <bpf/bpf_helpers.h>
5
6struct timer {
7	struct bpf_timer t;
8};
9
10struct lock {
11	struct bpf_spin_lock l;
12};
13
14struct {
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
21struct {
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
28static int timer_cb(void *map, int *key, struct timer *timer)
29{
30	return 0;
31}
32
33static 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
47static 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
59SEC("?raw_tp/sys_enter")
60int raw_tp_timer(void *ctx)
61{
62	timer_work();
63
64	return 0;
65}
66
67SEC("?tp/syscalls/sys_enter_nanosleep")
68int tp_timer(void *ctx)
69{
70	timer_work();
71
72	return 0;
73}
74
75SEC("?kprobe")
76int kprobe_timer(void *ctx)
77{
78	timer_work();
79
80	return 0;
81}
82
83SEC("?perf_event")
84int perf_event_timer(void *ctx)
85{
86	timer_work();
87
88	return 0;
89}
90
91SEC("?raw_tp/sys_enter")
92int raw_tp_spin_lock(void *ctx)
93{
94	spin_lock_work();
95
96	return 0;
97}
98
99SEC("?tp/syscalls/sys_enter_nanosleep")
100int tp_spin_lock(void *ctx)
101{
102	spin_lock_work();
103
104	return 0;
105}
106
107SEC("?kprobe")
108int kprobe_spin_lock(void *ctx)
109{
110	spin_lock_work();
111
112	return 0;
113}
114
115SEC("?perf_event")
116int perf_event_spin_lock(void *ctx)
117{
118	spin_lock_work();
119
120	return 0;
121}
122
123const char LICENSE[] SEC("license") = "GPL";
124