]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: Move arena-related headers into libarena
authorEmil Tsalapatis <emil@etsalapatis.com>
Sun, 26 Apr 2026 19:03:33 +0000 (15:03 -0400)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 27 Apr 2026 01:12:22 +0000 (18:12 -0700)
The BPF selftest headers include functionality that is
specific to arenas and is required by libarena. Keep libarena
self-contained by moving all functionality into its include/
directory. Also add libarena/include to the standard include
paths for the selftests to make the moved headers easy to
access by existing selftests.

Some functionality is required by libarena but not strictly
arena-related. We still move it to the libarena/include path,
which is an upgrade from directly accessing them from the
selftests/bpf directory using relative paths.

A new bpf_may_goto.h file is split off of bpf_experimental.h.
bpf_arena_spin_lock.h and bpf_arena_common.h are moved to
libarena/include. bpf_atomic.h is also moved to libarena
because it is necessary for arena spinlocks.

For bpf_arena_spin_lock.h, mark the spinlock state array as __weak
to define the spinlock state array in the header while also
being compatible with multi-compilation unit programs. While
we're at it, we remove unnecessary definitions from existing
test programs.

Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://lore.kernel.org/r/20260426190338.4615-4-emil@etsalapatis.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
21 files changed:
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/bpf_arena_alloc.h
tools/testing/selftests/bpf/bpf_arena_list.h
tools/testing/selftests/bpf/bpf_arena_strsearch.h
tools/testing/selftests/bpf/bpf_experimental.h
tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h [moved from tools/testing/selftests/bpf/bpf_arena_common.h with 100% similarity]
tools/testing/selftests/bpf/libarena/include/bpf_arena_spin_lock.h [moved from tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h with 98% similarity]
tools/testing/selftests/bpf/libarena/include/bpf_atomic.h [moved from tools/testing/selftests/bpf/bpf_atomic.h with 99% similarity]
tools/testing/selftests/bpf/libarena/include/bpf_may_goto.h [new file with mode: 0644]
tools/testing/selftests/bpf/libarena/include/libarena/common.h
tools/testing/selftests/bpf/prog_tests/arena_spin_lock.c
tools/testing/selftests/bpf/progs/arena_atomics.c
tools/testing/selftests/bpf/progs/arena_spin_lock.c
tools/testing/selftests/bpf/progs/compute_live_registers.c
tools/testing/selftests/bpf/progs/lpm_trie_bench.c
tools/testing/selftests/bpf/progs/stream.c
tools/testing/selftests/bpf/progs/verifier_arena.c
tools/testing/selftests/bpf/progs/verifier_arena_globals1.c
tools/testing/selftests/bpf/progs/verifier_arena_globals2.c
tools/testing/selftests/bpf/progs/verifier_arena_large.c
tools/testing/selftests/bpf/progs/verifier_ldsx.c

index 9fe30a665c2e29a5d2252c04e3fc0b4dcc5c7c7b..71c7873c4b159bbc719cc06953d63861cf5f693b 100644 (file)
@@ -56,7 +56,8 @@ CFLAGS += -g $(OPT_FLAGS) -rdynamic -std=gnu11                                \
          -Wno-unused-but-set-variable                                  \
          $(GENFLAGS) $(SAN_CFLAGS) $(LIBELF_CFLAGS)                    \
          -I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR)          \
-         -I$(TOOLSINCDIR) -I$(TOOLSARCHINCDIR) -I$(APIDIR) -I$(OUTPUT)
+         -I$(TOOLSINCDIR) -I$(TOOLSARCHINCDIR) -I$(APIDIR) -I$(OUTPUT) \
+         -I$(CURDIR)/libarena/include
 LDFLAGS += $(SAN_LDFLAGS)
 LDLIBS += $(LIBELF_LIBS) -lz -lrt -lpthread
 
@@ -444,6 +445,7 @@ endif
 CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH))
 BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN)    \
             -I$(INCLUDE_DIR) -I$(CURDIR) -I$(APIDIR)                   \
+            -I$(CURDIR)/libarena/include                               \
             -I$(abspath $(OUTPUT)/../usr/include)                      \
             -std=gnu11                                                 \
             -fno-strict-aliasing                                       \
index c27678299e0c96506488c395385cbf225866c531..cda147fd9d259f1e6e1a9799beeed3a364323a57 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
 #pragma once
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 #ifndef __round_mask
 #define __round_mask(x, y) ((__typeof__(x))((y)-1))
index e16fa7d95fcf06ffa5000ce03b73b8e58f1d44b9..1af2ffc27d9cb1dcfe28afdf1f694ea88e8b6eaf 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
 #pragma once
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 struct arena_list_node;
 
index c1b6eaa905bbd67c6232036394a4c6f2d67abfad..f0d575daef5aaf7df3b794e7c8bf62b2c6820281 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
 #pragma once
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 __noinline int bpf_arena_strlen(const char __arena *s __arg_arena)
 {
index 2234bd6bc9d3fcb8ca9a3e4a243cf46f8971b428..d1db355e872b9d7cbd104c539c25e53f4d2d76c3 100644 (file)
@@ -5,6 +5,7 @@
 #include <bpf/bpf_tracing.h>
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_core_read.h>
+#include <bpf_may_goto.h>
 
 #define __contains(name, node) __attribute__((btf_decl_tag("contains:" #name ":" #node)))
 
@@ -204,89 +205,6 @@ l_true:                                                                                            \
        })
 #endif
 
-/*
- * Note that cond_break can only be portably used in the body of a breakable
- * construct, whereas can_loop can be used anywhere.
- */
-#ifdef __BPF_FEATURE_MAY_GOTO
-#define can_loop                                       \
-       ({ __label__ l_break, l_continue;               \
-       bool ret = true;                                \
-       asm volatile goto("may_goto %l[l_break]"        \
-                     :::: l_break);                    \
-       goto l_continue;                                \
-       l_break: ret = false;                           \
-       l_continue:;                                    \
-       ret;                                            \
-       })
-
-#define __cond_break(expr)                             \
-       ({ __label__ l_break, l_continue;               \
-       asm volatile goto("may_goto %l[l_break]"        \
-                     :::: l_break);                    \
-       goto l_continue;                                \
-       l_break: expr;                                  \
-       l_continue:;                                    \
-       })
-#else
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-#define can_loop                                       \
-       ({ __label__ l_break, l_continue;               \
-       bool ret = true;                                \
-       asm volatile goto("1:.byte 0xe5;                \
-                     .byte 0;                          \
-                     .long ((%l[l_break] - 1b - 8) / 8) & 0xffff;      \
-                     .short 0"                         \
-                     :::: l_break);                    \
-       goto l_continue;                                \
-       l_break: ret = false;                           \
-       l_continue:;                                    \
-       ret;                                            \
-       })
-
-#define __cond_break(expr)                             \
-       ({ __label__ l_break, l_continue;               \
-       asm volatile goto("1:.byte 0xe5;                \
-                     .byte 0;                          \
-                     .long ((%l[l_break] - 1b - 8) / 8) & 0xffff;      \
-                     .short 0"                         \
-                     :::: l_break);                    \
-       goto l_continue;                                \
-       l_break: expr;                                  \
-       l_continue:;                                    \
-       })
-#else
-#define can_loop                                       \
-       ({ __label__ l_break, l_continue;               \
-       bool ret = true;                                \
-       asm volatile goto("1:.byte 0xe5;                \
-                     .byte 0;                          \
-                     .long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16;      \
-                     .short 0"                         \
-                     :::: l_break);                    \
-       goto l_continue;                                \
-       l_break: ret = false;                           \
-       l_continue:;                                    \
-       ret;                                            \
-       })
-
-#define __cond_break(expr)                             \
-       ({ __label__ l_break, l_continue;               \
-       asm volatile goto("1:.byte 0xe5;                \
-                     .byte 0;                          \
-                     .long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16;      \
-                     .short 0"                         \
-                     :::: l_break);                    \
-       goto l_continue;                                \
-       l_break: expr;                                  \
-       l_continue:;                                    \
-       })
-#endif
-#endif
-
-#define cond_break __cond_break(break)
-#define cond_break_label(label) __cond_break(goto label)
-
 #ifndef bpf_nop_mov
 #define bpf_nop_mov(var) \
        asm volatile("%[reg]=%[reg]"::[reg]"r"((short)var))
similarity index 98%
rename from tools/testing/selftests/bpf/progs/bpf_arena_spin_lock.h
rename to tools/testing/selftests/bpf/libarena/include/bpf_arena_spin_lock.h
index f90531cf3ee59edfe83404e3758653c2f36af1de..164638690a4df80dfb72f5218a11e2adee50c086 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
-#include "bpf_atomic.h"
+#include <bpf_atomic.h>
 
 #define arch_mcs_spin_lock_contended_label(l, label) smp_cond_load_acquire_label(l, VAL, label)
 #define arch_mcs_spin_unlock_contended(l) smp_store_release((l), 1)
@@ -107,7 +107,12 @@ struct arena_qnode {
 #define _Q_LOCKED_VAL          (1U << _Q_LOCKED_OFFSET)
 #define _Q_PENDING_VAL         (1U << _Q_PENDING_OFFSET)
 
-struct arena_qnode __arena qnodes[_Q_MAX_CPUS][_Q_MAX_NODES];
+/*
+ * The qnodes are marked __weak so we can define them in the header
+ * while still ensuring all compilation units use the same struct
+ * instance.
+ */
+struct arena_qnode __weak __arena __hidden qnodes[_Q_MAX_CPUS][_Q_MAX_NODES];
 
 static inline u32 encode_tail(int cpu, int idx)
 {
@@ -240,7 +245,7 @@ static __always_inline int arena_spin_trylock(arena_spinlock_t __arena *lock)
        return likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL));
 }
 
-__noinline
+__noinline __weak
 int arena_spin_lock_slowpath(arena_spinlock_t __arena __arg_arena *lock, u32 val)
 {
        struct arena_mcs_spinlock __arena *prev, *next, *node0, *node;
similarity index 99%
rename from tools/testing/selftests/bpf/bpf_atomic.h
rename to tools/testing/selftests/bpf/libarena/include/bpf_atomic.h
index d89a22d63c1c04ba40b9cb7ded41a827c7f45c57..b7b23043192950b95f247be6fcb387e970c06d2b 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
-#include "bpf_experimental.h"
+#include <bpf_may_goto.h>
 
 extern bool CONFIG_X86_64 __kconfig __weak;
 
diff --git a/tools/testing/selftests/bpf/libarena/include/bpf_may_goto.h b/tools/testing/selftests/bpf/libarena/include/bpf_may_goto.h
new file mode 100644 (file)
index 0000000..9ba9068
--- /dev/null
@@ -0,0 +1,84 @@
+#pragma once
+
+/*
+ * Note that cond_break can only be portably used in the body of a breakable
+ * construct, whereas can_loop can be used anywhere.
+ */
+#ifdef __BPF_FEATURE_MAY_GOTO
+#define can_loop                                       \
+       ({ __label__ l_break, l_continue;               \
+       bool ret = true;                                \
+       asm volatile goto("may_goto %l[l_break]"        \
+                     :::: l_break);                    \
+       goto l_continue;                                \
+       l_break: ret = false;                           \
+       l_continue:;                                    \
+       ret;                                            \
+       })
+
+#define __cond_break(expr)                             \
+       ({ __label__ l_break, l_continue;               \
+       asm volatile goto("may_goto %l[l_break]"        \
+                     :::: l_break);                    \
+       goto l_continue;                                \
+       l_break: expr;                                  \
+       l_continue:;                                    \
+       })
+#else
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define can_loop                                       \
+       ({ __label__ l_break, l_continue;               \
+       bool ret = true;                                \
+       asm volatile goto("1:.byte 0xe5;                \
+                     .byte 0;                          \
+                     .long ((%l[l_break] - 1b - 8) / 8) & 0xffff;      \
+                     .short 0"                         \
+                     :::: l_break);                    \
+       goto l_continue;                                \
+       l_break: ret = false;                           \
+       l_continue:;                                    \
+       ret;                                            \
+       })
+
+#define __cond_break(expr)                             \
+       ({ __label__ l_break, l_continue;               \
+       asm volatile goto("1:.byte 0xe5;                \
+                     .byte 0;                          \
+                     .long ((%l[l_break] - 1b - 8) / 8) & 0xffff;      \
+                     .short 0"                         \
+                     :::: l_break);                    \
+       goto l_continue;                                \
+       l_break: expr;                                  \
+       l_continue:;                                    \
+       })
+#else
+#define can_loop                                       \
+       ({ __label__ l_break, l_continue;               \
+       bool ret = true;                                \
+       asm volatile goto("1:.byte 0xe5;                \
+                     .byte 0;                          \
+                     .long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16;      \
+                     .short 0"                         \
+                     :::: l_break);                    \
+       goto l_continue;                                \
+       l_break: ret = false;                           \
+       l_continue:;                                    \
+       ret;                                            \
+       })
+
+#define __cond_break(expr)                             \
+       ({ __label__ l_break, l_continue;               \
+       asm volatile goto("1:.byte 0xe5;                \
+                     .byte 0;                          \
+                     .long (((%l[l_break] - 1b - 8) / 8) & 0xffff) << 16;      \
+                     .short 0"                         \
+                     :::: l_break);                    \
+       goto l_continue;                                \
+       l_break: expr;                                  \
+       l_continue:;                                    \
+       })
+#endif
+#endif
+
+#define cond_break __cond_break(break)
+#define cond_break_label(label) __cond_break(goto label)
index 92b67b20ed153b95658d54646ccab34bd9f57d8b..d088f3e75798485c0df3a0d6f8b24b45306864ad 100644 (file)
@@ -6,8 +6,8 @@
 
 #include <vmlinux.h>
 
-#include "../../bpf_arena_common.h"
-#include "../../progs/bpf_arena_spin_lock.h"
+#include <bpf_arena_common.h>
+#include <bpf_arena_spin_lock.h>
 
 #include <asm-generic/errno.h>
 
index 693fd86fbde622f90c00a166e4871070875e356b..acb9d53b59733ffdeaa2020105e3b2c4a68c23a6 100644 (file)
@@ -5,13 +5,6 @@
 #include <sys/sysinfo.h>
 
 struct __qspinlock { int val; };
-typedef struct __qspinlock arena_spinlock_t;
-
-struct arena_qnode {
-       unsigned long next;
-       int count;
-       int locked;
-};
 
 #include "arena_spin_lock.skel.h"
 
index d1841aac94a22f646fc9a767104e47a6e8353d2b..2e7751a853999b04cc42c6c005450fb757bb24b8 100644 (file)
@@ -5,7 +5,7 @@
 #include <bpf/bpf_tracing.h>
 #include <stdbool.h>
 #include <stdatomic.h>
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 #include "../../../include/linux/filter.h"
 #include "bpf_misc.h"
 
index 086b57a426cf5ae999351d1a70d6741eca58009d..7236d92d382f1a23ab3e2d282bccda9991be21e9 100644 (file)
@@ -4,7 +4,7 @@
 #include <bpf/bpf_tracing.h>
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
-#include "bpf_arena_spin_lock.h"
+#include <bpf_arena_spin_lock.h>
 
 struct {
        __uint(type, BPF_MAP_TYPE_ARENA);
index f05e120f345087844a57e1f53b67a54d746da75b..d055fc7b3b95dab06c2bf99dce152fde5526ecb0 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 #include "../../../include/linux/filter.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 #include "bpf_misc.h"
 
 struct {
index a0e6ebd5507a9200de1ebfe22583439dc29ba944..2831cf4445e8487d70707939e5b159903f96bf9c 100644 (file)
@@ -7,7 +7,7 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_core_read.h>
 #include "bpf_misc.h"
-#include "bpf_atomic.h"
+#include <bpf_atomic.h>
 #include "progs/lpm_trie.h"
 
 #define BPF_OBJ_NAME_LEN 16U
index 6f999ba951a3c2e3f88361b26597537296f7187c..92ba1d72e0ece4320140a11b50b9cd983e6722a7 100644 (file)
@@ -5,7 +5,7 @@
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
 #include "bpf_experimental.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 struct arr_elem {
        struct bpf_res_spin_lock lock;
index 62e282f4448aaa481376b2c63bc4868a69b29e7c..89d72c8d756ac78cc6871d158e21164ad70baa20 100644 (file)
@@ -8,7 +8,7 @@
 #include <bpf/bpf_tracing.h>
 #include "bpf_misc.h"
 #include "bpf_experimental.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 #define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
 
index 83182ddbfb9517fd0eb9fa2c94841d4767775c56..45d364b0bc85d1dac8650bf1a0ca0c589b51e232 100644 (file)
@@ -6,7 +6,7 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>
 #include "bpf_experimental.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 #include "bpf_misc.h"
 
 #define ARENA_PAGES (1UL<< (32 - __builtin_ffs(__PAGE_SIZE) + 1))
index e6bd7b61f9f13e37ad4435d87371a10ae3eca72a..b51594dbc0053b7d45574c9b2299cb2ea4b87e0f 100644 (file)
@@ -7,7 +7,7 @@
 #include <bpf/bpf_tracing.h>
 #include "bpf_misc.h"
 #include "bpf_experimental.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 #define ARENA_PAGES (32)
 
index 5f7e7afee169edb83a095fd7115f8d73c9671360..6ab8730d487820d787a787d6cca6f74ad915e9b6 100644 (file)
@@ -7,7 +7,7 @@
 #include <bpf/bpf_tracing.h>
 #include "bpf_misc.h"
 #include "bpf_experimental.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 #define ARENA_SIZE (1ull << 32)
 
index c8494b682c3193460837568182090d225949ff26..1026524a1983c60cad9f670c1d8493ed028ef704 100644 (file)
@@ -3,7 +3,7 @@
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
-#include "bpf_arena_common.h"
+#include <bpf_arena_common.h>
 
 #if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
        (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \