xref: /linux/tools/testing/selftests/bpf/progs/timer_lockup.c (revision c94cd9508b1335b949fd13ebd269313c65492df0)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/bpf.h>
4 #include <time.h>
5 #include <errno.h>
6 #include <bpf/bpf_helpers.h>
7 #include <bpf/bpf_tracing.h>
8 #include "bpf_misc.h"
9 
10 char _license[] SEC("license") = "GPL";
11 
12 struct elem {
13 	struct bpf_timer t;
14 };
15 
16 struct {
17 	__uint(type, BPF_MAP_TYPE_ARRAY);
18 	__uint(max_entries, 1);
19 	__type(key, int);
20 	__type(value, struct elem);
21 } timer1_map SEC(".maps");
22 
23 struct {
24 	__uint(type, BPF_MAP_TYPE_ARRAY);
25 	__uint(max_entries, 1);
26 	__type(key, int);
27 	__type(value, struct elem);
28 } timer2_map SEC(".maps");
29 
30 int timer1_err;
31 int timer2_err;
32 
33 static int timer_cb1(void *map, int *k, struct elem *v)
34 {
35 	struct bpf_timer *timer;
36 	int key = 0;
37 
38 	timer = bpf_map_lookup_elem(&timer2_map, &key);
39 	if (timer)
40 		timer2_err = bpf_timer_cancel(timer);
41 
42 	return 0;
43 }
44 
45 static int timer_cb2(void *map, int *k, struct elem *v)
46 {
47 	struct bpf_timer *timer;
48 	int key = 0;
49 
50 	timer = bpf_map_lookup_elem(&timer1_map, &key);
51 	if (timer)
52 		timer1_err = bpf_timer_cancel(timer);
53 
54 	return 0;
55 }
56 
57 SEC("tc")
58 int timer1_prog(void *ctx)
59 {
60 	struct bpf_timer *timer;
61 	int key = 0;
62 
63 	timer = bpf_map_lookup_elem(&timer1_map, &key);
64 	if (timer) {
65 		bpf_timer_init(timer, &timer1_map, CLOCK_BOOTTIME);
66 		bpf_timer_set_callback(timer, timer_cb1);
67 		bpf_timer_start(timer, 1, BPF_F_TIMER_CPU_PIN);
68 	}
69 
70 	return 0;
71 }
72 
73 SEC("tc")
74 int timer2_prog(void *ctx)
75 {
76 	struct bpf_timer *timer;
77 	int key = 0;
78 
79 	timer = bpf_map_lookup_elem(&timer2_map, &key);
80 	if (timer) {
81 		bpf_timer_init(timer, &timer2_map, CLOCK_BOOTTIME);
82 		bpf_timer_set_callback(timer, timer_cb2);
83 		bpf_timer_start(timer, 1, BPF_F_TIMER_CPU_PIN);
84 	}
85 
86 	return 0;
87 }
88