For systems having CONFIG_NR_CPUS set to > 1024 in kernel config
the selftest fails even though the current number of online cpus
is less. For example, on powerpc the default value for
CONFIG_NR_CPUS is set to 8192.
get_nprocs() is used to get the number of available cpus in test
driver code and the same is passed to the bpf program using rodata.
Also the selftest is skipped incase bpf program returns EOPNOTSUPP,
with a descriptive message logged.
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
---
.../bpf/prog_tests/arena_spin_lock.c | 23 +++++++++++++++++--
.../selftests/bpf/progs/arena_spin_lock.c | 8 ++++++-
.../selftests/bpf/progs/bpf_arena_spin_lock.h | 4 +---
3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c b/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c
index 0223fce4db2b..fa0b4f0240a3 100644
--- a/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c
+++ b/tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c
@@ -40,8 +40,13 @@ static void *spin_lock_thread(void *arg)
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "test_run err");
+
+ if (topts.retval == -EOPNOTSUPP)
+ goto end;
+
ASSERT_EQ((int)topts.retval, 0, "test_run retval");
+end:
pthread_exit(arg);
}
@@ -60,9 +65,16 @@ static void test_arena_spin_lock_size(int size)
return;
}
- skel = arena_spin_lock__open_and_load();
- if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open_and_load"))
+ skel = arena_spin_lock__open();
+ if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open"))
return;
+
+ skel->rodata->nr_cpus = get_nprocs();
+
+ err = arena_spin_lock__load(skel);
+ if (!ASSERT_OK(err, "arena_spin_lock__load"))
+ goto end;
+
if (skel->data->test_skip == 2) {
test__skip();
goto end;
@@ -86,6 +98,13 @@ static void test_arena_spin_lock_size(int size)
goto end_barrier;
}
+ if (skel->data->test_skip == 2) {
+ printf("%s:SKIP: %d online CPUs exceed the maximum supported by arena spinlock\n",
+ __func__, get_nprocs());
+ test__skip();
+ goto end_barrier;
+ }
+
ASSERT_EQ(skel->bss->counter, repeat * nthreads, "check counter value");
end_barrier:
diff --git a/tools/testing/selftests/bpf/progs/arena_spin_lock.c b/tools/testing/selftests/bpf/progs/arena_spin_lock.c
index c4500c37f85e..9ed5a3281fd4 100644
--- a/tools/testing/selftests/bpf/progs/arena_spin_lock.c
+++ b/tools/testing/selftests/bpf/progs/arena_spin_lock.c
@@ -4,6 +4,9 @@
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
+
+const volatile int nr_cpus;
+
#include "bpf_arena_spin_lock.h"
struct {
@@ -37,8 +40,11 @@ int prog(void *ctx)
#if defined(ENABLE_ATOMICS_TESTS) && defined(__BPF_FEATURE_ADDR_SPACE_CAST)
unsigned long flags;
- if ((ret = arena_spin_lock_irqsave(&lock, flags)))
+ if ((ret = arena_spin_lock_irqsave(&lock, flags))) {
+ if (ret == -EOPNOTSUPP)
+ test_skip = 2;
return ret;
+ }
if (counter != limit)
counter++;
bpf_repeat(cs_count);
diff --git a/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h b/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h
index d67466c1ff77..752131161315 100644
--- a/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h
+++ b/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h
@@ -20,8 +20,6 @@
#define __arena __attribute__((address_space(1)))
#endif
-extern unsigned long CONFIG_NR_CPUS __kconfig;
-
/*
* Typically, we'd just rely on the definition in vmlinux.h for qspinlock, but
* PowerPC overrides the definition to define lock->val as u32 instead of
@@ -494,7 +492,7 @@ static __always_inline int arena_spin_lock(arena_spinlock_t __arena *lock)
{
int val = 0;
- if (CONFIG_NR_CPUS > 1024)
+ if (nr_cpus > 1024)
return -EOPNOTSUPP;
bpf_preempt_disable();
--
2.43.5
On Mon, Aug 4, 2025 at 11:29 PM Saket Kumar Bhaskar <skb99@linux.ibm.com> wrote: > > @@ -60,9 +65,16 @@ static void test_arena_spin_lock_size(int size) > return; > } > > - skel = arena_spin_lock__open_and_load(); > - if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open_and_load")) > + skel = arena_spin_lock__open(); > + if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open")) > return; > + > + skel->rodata->nr_cpus = get_nprocs(); ... > --- a/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h > +++ b/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h > @@ -20,8 +20,6 @@ > #define __arena __attribute__((address_space(1))) > #endif > > -extern unsigned long CONFIG_NR_CPUS __kconfig; > - > /* > * Typically, we'd just rely on the definition in vmlinux.h for qspinlock, but > * PowerPC overrides the definition to define lock->val as u32 instead of > @@ -494,7 +492,7 @@ static __always_inline int arena_spin_lock(arena_spinlock_t __arena *lock) > { > int val = 0; > > - if (CONFIG_NR_CPUS > 1024) > + if (nr_cpus > 1024) > return -EOPNOTSUPP; We cannot do this. It will make arena_spin_lock much harder to use. BPF CI doesn't run on powerpc anyway, but you can document that this test is disable by creating selftests/bpf/DENYLIST.powerpc.
On Thu, Aug 07, 2025 at 03:21:42PM -0700, Alexei Starovoitov wrote: > On Mon, Aug 4, 2025 at 11:29 PM Saket Kumar Bhaskar <skb99@linux.ibm.com> wrote: > > > > @@ -60,9 +65,16 @@ static void test_arena_spin_lock_size(int size) > > return; > > } > > > > - skel = arena_spin_lock__open_and_load(); > > - if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open_and_load")) > > + skel = arena_spin_lock__open(); > > + if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open")) > > return; > > + > > + skel->rodata->nr_cpus = get_nprocs(); > > ... > > > --- a/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h > > +++ b/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h > > @@ -20,8 +20,6 @@ > > #define __arena __attribute__((address_space(1))) > > #endif > > > > -extern unsigned long CONFIG_NR_CPUS __kconfig; > > - > > /* > > * Typically, we'd just rely on the definition in vmlinux.h for qspinlock, but > > * PowerPC overrides the definition to define lock->val as u32 instead of > > @@ -494,7 +492,7 @@ static __always_inline int arena_spin_lock(arena_spinlock_t __arena *lock) > > { > > int val = 0; > > > > - if (CONFIG_NR_CPUS > 1024) > > + if (nr_cpus > 1024) > > return -EOPNOTSUPP; > > We cannot do this. It will make arena_spin_lock much harder to use. > BPF CI doesn't run on powerpc anyway, but you can document that this > test is disable by creating selftests/bpf/DENYLIST.powerpc. Hi Alexie, Sorry, I did not get it. Can you please help me to understand why it makes arena_spin_lock harder to use. Thanks, Saket
On Fri, Aug 8, 2025 at 8:29 AM Saket Kumar Bhaskar <skb99@linux.ibm.com> wrote: > > On Thu, Aug 07, 2025 at 03:21:42PM -0700, Alexei Starovoitov wrote: > > On Mon, Aug 4, 2025 at 11:29 PM Saket Kumar Bhaskar <skb99@linux.ibm.com> wrote: > > > > > > @@ -60,9 +65,16 @@ static void test_arena_spin_lock_size(int size) > > > return; > > > } > > > > > > - skel = arena_spin_lock__open_and_load(); > > > - if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open_and_load")) > > > + skel = arena_spin_lock__open(); > > > + if (!ASSERT_OK_PTR(skel, "arena_spin_lock__open")) > > > return; > > > + > > > + skel->rodata->nr_cpus = get_nprocs(); > > > > ... > > > > > --- a/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h > > > +++ b/tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h > > > @@ -20,8 +20,6 @@ > > > #define __arena __attribute__((address_space(1))) > > > #endif > > > > > > -extern unsigned long CONFIG_NR_CPUS __kconfig; > > > - > > > /* > > > * Typically, we'd just rely on the definition in vmlinux.h for qspinlock, but > > > * PowerPC overrides the definition to define lock->val as u32 instead of > > > @@ -494,7 +492,7 @@ static __always_inline int arena_spin_lock(arena_spinlock_t __arena *lock) > > > { > > > int val = 0; > > > > > > - if (CONFIG_NR_CPUS > 1024) > > > + if (nr_cpus > 1024) > > > return -EOPNOTSUPP; > > > > We cannot do this. It will make arena_spin_lock much harder to use. > > BPF CI doesn't run on powerpc anyway, but you can document that this > > test is disable by creating selftests/bpf/DENYLIST.powerpc. > Hi Alexie, > Sorry, I did not get it. Can you please help me to understand why it > makes arena_spin_lock harder to use. because requiring user space to do skel->rodata->nr_cpus = get_nprocs() is a headache.
© 2016 - 2025 Red Hat, Inc.