enable_stats attaches its program to sys_enter, so every syscall of the
system runs it. Once the program is detached, the test compares its
run_cnt to the number of runs the program counted itself.

Detaching doesn't wait for the runs already started on other CPUs, and
each of them increments count before run_cnt. With other tests making
syscalls in parallel, the test reads run_cnt one run behind count now
and then:

  test_enable_stats:FAIL:check_run_cnt_valid invalid run_cnt stats

Run the program with BPF_PROG_TEST_RUN instead of attaching it, so that
nothing else runs it and both counts are final when the test reads
them. As a single run can be shorter than the resolution of the clock,
run it until its run time shows, unless its runs aren't counted at all.

Fixes: 31a9f7fe9337 ("bpf: Add selftest for BPF_ENABLE_STATS")
Signed-off-by: Qiliang Yuan <[email protected]>
---
V1 -> V2:
- Run the program until its run time shows, as a single run can be
  shorter than the resolution of the clock (Sashiko)

v1: 
https://lore.kernel.org/r/20261008-selftests-bpf-enable-stats-inflight-v1-1-0cb92ee2c...@gmail.com
---
 .../selftests/bpf/prog_tests/enable_stats.c        | 26 +++++++++++++---------
 .../selftests/bpf/progs/test_enable_stats.c        |  2 +-
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/enable_stats.c 
b/tools/testing/selftests/bpf/prog_tests/enable_stats.c
index 75f85d0fe74a4..691a82a4d6d20 100644
--- a/tools/testing/selftests/bpf/prog_tests/enable_stats.c
+++ b/tools/testing/selftests/bpf/prog_tests/enable_stats.c
@@ -9,6 +9,7 @@ void test_enable_stats(void)
        struct bpf_prog_info info;
        __u32 info_len = sizeof(info);
        int duration = 0;
+       LIBBPF_OPTS(bpf_test_run_opts, topts);
 
        skel = test_enable_stats__open_and_load();
        if (CHECK(!skel, "skel_open_and_load", "skeleton open/load failed\n"))
@@ -20,18 +21,23 @@ void test_enable_stats(void)
                return;
        }
 
-       err = test_enable_stats__attach(skel);
-       if (CHECK(err, "attach_raw_tp", "err %d\n", err))
-               goto cleanup;
-
-       test_enable_stats__detach(skel);
-
        prog_fd = bpf_program__fd(skel->progs.test_enable_stats);
-       memset(&info, 0, info_len);
-       err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
-       if (CHECK(err, "get_prog_info",
-                 "failed to get bpf_prog_info for fd %d\n", prog_fd))
+
+       /*
+        * A single run can be too short for the clock to tell. Run the program
+        * until its run time shows, unless its runs aren't counted at all.
+        */
+       do {
+               err = bpf_prog_test_run_opts(prog_fd, &topts);
+               if (err)
+                       break;
+
+               memset(&info, 0, info_len);
+               err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
+       } while (!err && info.run_cnt && !info.run_time_ns);
+       if (CHECK(err, "run_and_get_prog_info", "err %d\n", err))
                goto cleanup;
+
        if (CHECK(info.run_time_ns == 0, "check_stats_enabled",
                  "failed to enable run_time_ns stats\n"))
                goto cleanup;
diff --git a/tools/testing/selftests/bpf/progs/test_enable_stats.c 
b/tools/testing/selftests/bpf/progs/test_enable_stats.c
index 1705097d01d7b..e28d674fc77ac 100644
--- a/tools/testing/selftests/bpf/progs/test_enable_stats.c
+++ b/tools/testing/selftests/bpf/progs/test_enable_stats.c
@@ -10,7 +10,7 @@ char _license[] SEC("license") = "GPL";
 
 __u64 count = 0;
 
-SEC("raw_tracepoint/sys_enter")
+SEC("raw_tp")
 int test_enable_stats(void *ctx)
 {
        __sync_fetch_and_add(&count, 1);

---
base-commit: e1d84a37cba984388988d2f1ddc84561413f0db2
change-id: 20261008-selftests-bpf-enable-stats-inflight-edfb36a280f3

Best regards,
-- 
Qiliang Yuan <[email protected]>


Reply via email to