From 34a5669421765ba3e33094b5393f0e18bd93825c Mon Sep 17 00:00:00 2001 From: Mykyta Yatsenko Date: Wed, 24 Sep 2025 12:28:10 +0100 Subject: [PATCH 1/2] selftests/bpf: fix flaky bpf_cookie selftest Problem: bpf_cookie selftest fails if it runs after task_work selftest: perf_event_open fails with errno=EINVAL. EINVAL indicates incorrect/invalid input argument, which in case of bpf_cookie can only point to sample_freq attribute. Possible root cause: When running task_work test, we can see that perf subsystem lowers kernel.perf_event_max_sample_rate which probably is the side-effect of the test that make bpf_cookie fail. Solution: Set perf_event_open sampling rate attribute for bpf_cookie the same as task_work - this is the most reliable solution for this, changing task_work sampling rate resulted in task_work test becoming flaky. Signed-off-by: Mykyta Yatsenko --- tools/testing/selftests/bpf/prog_tests/bpf_cookie.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c b/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c index 4a0670c056bad..53a3bf435479d 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c @@ -450,8 +450,8 @@ static void pe_subtest(struct test_bpf_cookie *skel) attr.size = sizeof(attr); attr.type = PERF_TYPE_SOFTWARE; attr.config = PERF_COUNT_SW_CPU_CLOCK; - attr.freq = 1; - attr.sample_freq = 10000; + attr.sample_period = 100000; + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); if (!ASSERT_GE(pfd, 0, "perf_fd")) goto cleanup; From 8b559e4d3bff662c3af23bc850f519a12f67b865 Mon Sep 17 00:00:00 2001 From: Mykyta Yatsenko Date: Wed, 24 Sep 2025 12:48:45 +0100 Subject: [PATCH 2/2] selftests/bpf: task_work selftest cleanup fixes task_work selftest does not properly handle cleanup during failures: * destroy bpf_link * perf event fd is passed to bpf_link, no need to close it if link was created successfully * goto cleanup if fork() failed, close pipe. Signed-off-by: Mykyta Yatsenko --- .../selftests/bpf/prog_tests/test_task_work.c | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/test_task_work.c b/tools/testing/selftests/bpf/prog_tests/test_task_work.c index 666585270fbf9..08d24c16e359d 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_task_work.c +++ b/tools/testing/selftests/bpf/prog_tests/test_task_work.c @@ -55,8 +55,8 @@ static void task_work_run(const char *prog_name, const char *map_name) struct task_work *skel; struct bpf_program *prog; struct bpf_map *map; - struct bpf_link *link; - int err, pe_fd = 0, pid, status, pipefd[2]; + struct bpf_link *link = NULL; + int err, pe_fd = -1, pid, status, pipefd[2]; char user_string[] = "hello world"; if (!ASSERT_NEQ(pipe(pipefd), -1, "pipe")) @@ -77,7 +77,11 @@ static void task_work_run(const char *prog_name, const char *map_name) (void)num; exit(0); } - ASSERT_GT(pid, 0, "fork() failed"); + if (!ASSERT_GT(pid, 0, "fork() failed")) { + close(pipefd[0]); + close(pipefd[1]); + return; + } skel = task_work__open(); if (!ASSERT_OK_PTR(skel, "task_work__open")) @@ -109,9 +113,12 @@ static void task_work_run(const char *prog_name, const char *map_name) } link = bpf_program__attach_perf_event(prog, pe_fd); - if (!ASSERT_OK_PTR(link, "attach_perf_event")) + if (!ASSERT_OK_PTR(link, "attach_perf_event")) { + link = NULL; goto cleanup; - + } + /* perf event fd ownership is passed to bpf_link */ + pe_fd = -1; close(pipefd[0]); write(pipefd[1], user_string, 1); close(pipefd[1]); @@ -126,8 +133,10 @@ static void task_work_run(const char *prog_name, const char *map_name) cleanup: if (pe_fd >= 0) close(pe_fd); + if (link) + bpf_link__destroy(link); task_work__destroy(skel); - if (pid) { + if (pid > 0) { close(pipefd[0]); write(pipefd[1], user_string, 1); close(pipefd[1]);