On Sat, Mar 13, 2021 at 11:19 AM Cong Wang <xiyou.wangcong@xxxxxxxxx> wrote: > > Please let me know what you think about introducing a timer > map, something like below: > > struct { > __uint(type, BPF_MAP_TYPE_TIMER); > } map SEC(".maps"); > > struct bpf_timer t; After some thoughts, I think the following solution is much better. We still need a timer map: struct { __uint(type, BPF_MAP_TYPE_TIMER); } map SEC(".maps"); However, its key is not a pointer to timer, it is a timer ID allocated with u32 bpf_timer_create(void *callback, void *arg, u64 flags); which returns a globally unique ID. So, we end up having code like this: u32 timer_id; static int timer_cb(void *arg) { // show how to rearm a timer u64 new_expires = ...; bpf_map_update_elem(&map, &timer_id, &new_expires, 0); } int bpf_timer_test(...) { u64 expires = ...; timer_id = bpf_timer_create(timer_cb, arg, 0); bpf_map_update_elem(&map, &timer_id, &expires, 0); // wait for timer deletion synchronously bpf_map_delete_elem(&map, &timer_id); } In kernel, we can use an IDR to allocate these ID's and save a kernel timer pointer for each ID there. With this solution, we don't need to change much in the verifier, probably only verifying the callback arg pointer for bpf_timer_create(). Any thoughts on this proposal? Thanks!