selftests/bpf: Add absolute timer test
authorTero Kristo <tero.kristo@linux.intel.com>
Thu, 2 Mar 2023 11:46:14 +0000 (13:46 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 3 Mar 2023 06:41:32 +0000 (22:41 -0800)
Add test for the absolute BPF timer under the existing timer tests. This
will run the timer two times with 1us expiration time, and then re-arm
the timer at ~35s in the future. At the end, it is verified that the
absolute timer expired exactly two times.

Signed-off-by: Tero Kristo <tero.kristo@linux.intel.com>
Link: https://lore.kernel.org/r/20230302114614.2985072-3-tero.kristo@linux.intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/timer.c
tools/testing/selftests/bpf/progs/timer.c

index 7eb04921485993a3499f664ca0000d4c88bca13e..290c21dbe65ab5546efdc17a50782515f0a20a43 100644 (file)
@@ -29,6 +29,9 @@ static int timer(struct timer *timer_skel)
        /* check that timer_cb2() was executed twice */
        ASSERT_EQ(timer_skel->bss->bss_data, 10, "bss_data");
 
+       /* check that timer_cb3() was executed twice */
+       ASSERT_EQ(timer_skel->bss->abs_data, 12, "abs_data");
+
        /* check that there were no errors in timer execution */
        ASSERT_EQ(timer_skel->bss->err, 0, "err");
 
index acda5c9cea9336e27848644b0f0b005b5647d006..9a16d95213e11527c15cfb44b4fef8d9415f47fa 100644 (file)
@@ -46,7 +46,15 @@ struct {
        __type(value, struct elem);
 } lru SEC(".maps");
 
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 1);
+       __type(key, int);
+       __type(value, struct elem);
+} abs_timer SEC(".maps");
+
 __u64 bss_data;
+__u64 abs_data;
 __u64 err;
 __u64 ok;
 __u64 callback_check = 52;
@@ -284,3 +292,40 @@ int BPF_PROG2(test2, int, a, int, b)
 
        return bpf_timer_test();
 }
+
+/* callback for absolute timer */
+static int timer_cb3(void *map, int *key, struct bpf_timer *timer)
+{
+       abs_data += 6;
+
+       if (abs_data < 12) {
+               bpf_timer_start(timer, bpf_ktime_get_boot_ns() + 1000,
+                               BPF_F_TIMER_ABS);
+       } else {
+               /* Re-arm timer ~35 seconds in future */
+               bpf_timer_start(timer, bpf_ktime_get_boot_ns() + (1ull << 35),
+                               BPF_F_TIMER_ABS);
+       }
+
+       return 0;
+}
+
+SEC("fentry/bpf_fentry_test3")
+int BPF_PROG2(test3, int, a)
+{
+       int key = 0;
+       struct bpf_timer *timer;
+
+       bpf_printk("test3");
+
+       timer = bpf_map_lookup_elem(&abs_timer, &key);
+       if (timer) {
+               if (bpf_timer_init(timer, &abs_timer, CLOCK_BOOTTIME) != 0)
+                       err |= 2048;
+               bpf_timer_set_callback(timer, timer_cb3);
+               bpf_timer_start(timer, bpf_ktime_get_boot_ns() + 1000,
+                               BPF_F_TIMER_ABS);
+       }
+
+       return 0;
+}