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