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" ) |
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" ) |
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 | |