]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Avoid spurious failures perf_link
authorSun Jian <sun.jian.kdev@gmail.com>
Thu, 5 Mar 2026 08:43:05 +0000 (16:43 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 19 Mar 2026 00:08:54 +0000 (17:08 -0700)
perf_link creates a system-wide perf event pinned to CPU 0 (pid=-1, cpu=0)
and also pins the test thread to CPU 0. Under concurrent selftests this
can lead to cross-test interference and CPU 0 contention, making the test
flaky.

Create a per-task perf event instead (pid=0, cpu=-1) and drop CPU pinning
from burn_cpu(). Use barrier() to prevent the burn loop from being
optimized away. Drop the serial_ prefix so the test can run in parallel.
Also remove the stale TODO comment.

Tested:
  ./test_progs -t perf_link -vv
  ./test_progs -j$(nproc) -t perf_link -vv
  for i in $(seq 1 50); do ./test_progs -j$(nproc) -t perf_link; done

Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260305084306.283983-1-sun.jian.kdev@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/perf_link.c

index d940ff87fa0802ee497127d70dff466efcb54ec7..9e3a0d217af8fbe2ec9112cdf7ad99833490cac7 100644 (file)
@@ -1,8 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2021 Facebook */
 #define _GNU_SOURCE
-#include <pthread.h>
-#include <sched.h>
+#include <linux/compiler.h>
 #include <test_progs.h>
 #include "testing_helpers.h"
 #include "test_perf_link.skel.h"
 
 static void burn_cpu(void)
 {
-       volatile int j = 0;
-       cpu_set_t cpu_set;
-       int i, err;
-
-       /* generate some branches on cpu 0 */
-       CPU_ZERO(&cpu_set);
-       CPU_SET(0, &cpu_set);
-       err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
-       ASSERT_OK(err, "set_thread_affinity");
+       int i;
 
        /* spin the loop for a while (random high number) */
        for (i = 0; i < 1000000; ++i)
-               ++j;
+               barrier();
 }
 
-/* TODO: often fails in concurrent mode */
-void serial_test_perf_link(void)
+void test_perf_link(void)
 {
        struct test_perf_link *skel = NULL;
        struct perf_event_attr attr;
@@ -45,7 +35,7 @@ void serial_test_perf_link(void)
        attr.config = PERF_COUNT_SW_CPU_CLOCK;
        attr.freq = 1;
        attr.sample_freq = 1000;
-       pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);
+       pfd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, PERF_FLAG_FD_CLOEXEC);
        if (!ASSERT_GE(pfd, 0, "perf_fd"))
                goto cleanup;