0001
0002 #include <time.h>
0003 #include <linux/bpf.h>
0004 #include <bpf/bpf_helpers.h>
0005
0006 struct timer {
0007 struct bpf_timer t;
0008 };
0009
0010 struct lock {
0011 struct bpf_spin_lock l;
0012 };
0013
0014 struct {
0015 __uint(type, BPF_MAP_TYPE_ARRAY);
0016 __uint(max_entries, 1);
0017 __type(key, __u32);
0018 __type(value, struct timer);
0019 } timers SEC(".maps");
0020
0021 struct {
0022 __uint(type, BPF_MAP_TYPE_ARRAY);
0023 __uint(max_entries, 1);
0024 __type(key, __u32);
0025 __type(value, struct lock);
0026 } locks SEC(".maps");
0027
0028 static int timer_cb(void *map, int *key, struct timer *timer)
0029 {
0030 return 0;
0031 }
0032
0033 static void timer_work(void)
0034 {
0035 struct timer *timer;
0036 const int key = 0;
0037
0038 timer = bpf_map_lookup_elem(&timers, &key);
0039 if (timer) {
0040 bpf_timer_init(&timer->t, &timers, CLOCK_MONOTONIC);
0041 bpf_timer_set_callback(&timer->t, timer_cb);
0042 bpf_timer_start(&timer->t, 10E9, 0);
0043 bpf_timer_cancel(&timer->t);
0044 }
0045 }
0046
0047 static void spin_lock_work(void)
0048 {
0049 const int key = 0;
0050 struct lock *lock;
0051
0052 lock = bpf_map_lookup_elem(&locks, &key);
0053 if (lock) {
0054 bpf_spin_lock(&lock->l);
0055 bpf_spin_unlock(&lock->l);
0056 }
0057 }
0058
0059 SEC("?raw_tp/sys_enter")
0060 int raw_tp_timer(void *ctx)
0061 {
0062 timer_work();
0063
0064 return 0;
0065 }
0066
0067 SEC("?tp/syscalls/sys_enter_nanosleep")
0068 int tp_timer(void *ctx)
0069 {
0070 timer_work();
0071
0072 return 0;
0073 }
0074
0075 SEC("?kprobe/sys_nanosleep")
0076 int kprobe_timer(void *ctx)
0077 {
0078 timer_work();
0079
0080 return 0;
0081 }
0082
0083 SEC("?perf_event")
0084 int perf_event_timer(void *ctx)
0085 {
0086 timer_work();
0087
0088 return 0;
0089 }
0090
0091 SEC("?raw_tp/sys_enter")
0092 int raw_tp_spin_lock(void *ctx)
0093 {
0094 spin_lock_work();
0095
0096 return 0;
0097 }
0098
0099 SEC("?tp/syscalls/sys_enter_nanosleep")
0100 int tp_spin_lock(void *ctx)
0101 {
0102 spin_lock_work();
0103
0104 return 0;
0105 }
0106
0107 SEC("?kprobe/sys_nanosleep")
0108 int kprobe_spin_lock(void *ctx)
0109 {
0110 spin_lock_work();
0111
0112 return 0;
0113 }
0114
0115 SEC("?perf_event")
0116 int perf_event_spin_lock(void *ctx)
0117 {
0118 spin_lock_work();
0119
0120 return 0;
0121 }
0122
0123 const char LICENSE[] SEC("license") = "GPL";