1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ 3 #include <vmlinux.h> 4 #include <bpf/bpf_helpers.h> 5 #include <bpf/bpf_tracing.h> 6 7 #define CLOCK_MONOTONIC 1 8 9 char _license[] SEC("license") = "GPL"; 10 11 struct elem { 12 struct bpf_timer timer; 13 }; 14 15 struct { 16 __uint(type, BPF_MAP_TYPE_ARRAY); 17 __uint(max_entries, 1); 18 __type(key, int); 19 __type(value, struct elem); 20 } timer_map SEC(".maps"); 21 22 volatile int in_timer_start; 23 volatile int tp_called; 24 25 static int timer_cb(void *map, int *key, struct elem *value) 26 { 27 return 0; 28 } 29 30 SEC("tp_btf/hrtimer_cancel") 31 int BPF_PROG(tp_hrtimer_cancel, struct hrtimer *hrtimer) 32 { 33 struct bpf_timer *timer; 34 static bool called = false; 35 int key = 0; 36 37 if (!in_timer_start) 38 return 0; 39 40 tp_called = 1; 41 timer = bpf_map_lookup_elem(&timer_map, &key); 42 43 /* 44 * Call bpf_timer_start() from the tracepoint within hrtimer logic 45 * on the same timer to make sure it doesn't deadlock, 46 * and do it once. 47 */ 48 if (!called) { 49 called = true; 50 bpf_timer_start(timer, 1000000000, 0); 51 } 52 return 0; 53 } 54 55 SEC("syscall") 56 int start_timer(void *ctx) 57 { 58 struct bpf_timer *timer; 59 int key = 0; 60 61 timer = bpf_map_lookup_elem(&timer_map, &key); 62 /* claude may complain here that there is no NULL check. Ignoring it. */ 63 bpf_timer_init(timer, &timer_map, CLOCK_MONOTONIC); 64 bpf_timer_set_callback(timer, timer_cb); 65 66 /* 67 * call hrtimer_start() twice, so that 2nd call does 68 * remove_hrtimer() and trace_hrtimer_cancel() tracepoint. 69 */ 70 in_timer_start = 1; 71 bpf_timer_start(timer, 1000000000, 0); 72 bpf_timer_start(timer, 1000000000, 0); 73 in_timer_start = 0; 74 return 0; 75 } 76