public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Matt Bobrowski <mattbobrowski@google.com>
To: Emil Tsalapatis <emil@etsalapatis.com>
Cc: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org,
	memxor@gmail.com, daniel@iogearbox.net, eddyz87@gmail.com,
	song@kernel.org
Subject: Re: [PATCH bpf-next v8 2/8] selftests/bpf: Add basic libarena scaffolding
Date: Thu, 23 Apr 2026 08:24:42 +0000	[thread overview]
Message-ID: <aenXSvDSN98azW_T@google.com> (raw)
In-Reply-To: <20260421165037.4736-3-emil@etsalapatis.com>

On Tue, Apr 21, 2026 at 12:50:31PM -0400, Emil Tsalapatis wrote:
> Add initial code for an arena-based BPF library. The current commit
> introduces a test runner and Makefile for the library. Library code
> can be added just by including the source file in the library's src/
> subdirectory. Future commits will introduce the library code itself.
> 
> The current commit also includes a standalone test runner. This is
> to keep libarena self-contained and testable even when copied out
> of the kernel tree. Subsequent commits add integration with test_progs.
> 
> The code includes workarounds that are removed in subsequent patches,
> like the qnode definitions for selftest.c. This is to ensure
> bisectability.
> 
> Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
> ---
>  tools/testing/selftests/bpf/.gitignore        |   1 +
>  tools/testing/selftests/bpf/Makefile          |  27 +++
>  tools/testing/selftests/bpf/libarena/Makefile |  75 ++++++++
>  .../selftests/bpf/libarena/include/common.h   |  66 ++++++++
>  .../bpf/libarena/include/selftest_helpers.h   |  99 +++++++++++
>  .../bpf/libarena/selftests/selftest.c         | 160 ++++++++++++++++++
>  .../selftests/bpf/libarena/src/common.bpf.c   |  62 +++++++
>  7 files changed, 490 insertions(+)
>  create mode 100644 tools/testing/selftests/bpf/libarena/Makefile
>  create mode 100644 tools/testing/selftests/bpf/libarena/include/common.h
>  create mode 100644 tools/testing/selftests/bpf/libarena/include/selftest_helpers.h
>  create mode 100644 tools/testing/selftests/bpf/libarena/selftests/selftest.c
>  create mode 100644 tools/testing/selftests/bpf/libarena/src/common.bpf.c
> 
> diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
> index bfdc5518ecc8..7f1960d6b59e 100644
> --- a/tools/testing/selftests/bpf/.gitignore
> +++ b/tools/testing/selftests/bpf/.gitignore
> @@ -49,3 +49,4 @@ verification_cert.h
>  *.BTF.base
>  usdt_1
>  usdt_2
> +libarena/test_libarena
> diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> index f75c4f52c028..a8d94f23a9c6 100644
> --- a/tools/testing/selftests/bpf/Makefile
> +++ b/tools/testing/selftests/bpf/Makefile
> @@ -153,6 +153,7 @@ override define CLEAN
>  	$(Q)$(RM) -r $(TEST_KMODS)
>  	$(Q)$(RM) -r $(EXTRA_CLEAN)
>  	$(Q)$(MAKE) -C test_kmods clean
> +	$(Q)$(MAKE) -C libarena clean
>  	$(Q)$(MAKE) docs-clean
>  endef
>  
> @@ -524,6 +525,7 @@ LINKED_BPF_OBJS := $(foreach skel,$(LINKED_SKELS),$($(skel)-deps))
>  LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.c,$(LINKED_BPF_OBJS))
>  
>  HEADERS_FOR_BPF_OBJS := $(wildcard $(BPFDIR)/*.bpf.h)		\
> +			$(wildcard $(CURDIR)/libarena/include/*.[ch])	\
>  			$(addprefix $(BPFDIR)/,	bpf_core_read.h	\
>  			                        bpf_endian.h	\
>  						bpf_helpers.h	\
> @@ -739,6 +741,28 @@ $(VERIFY_SIG_HDR): $(VERIFICATION_CERT)
>  	 echo "};"; \
>  	 echo "unsigned int test_progs_verification_cert_len = $$(wc -c < $<);") > $@
>  
> +LIBARENA_MAKE_ARGS = \
> +		BPFTOOL="$(BPFTOOL)" \
> +		INCLUDE_DIR="$(INCLUDE_DIR)" \
> +		LIBBPF_INCLUDE="$(HOST_INCLUDE_DIR)" \
> +		BPFOBJ="$(BPFOBJ)" \
> +		LDLIBS="$(LDLIBS) -lzstd" \
> +		CLANG="$(CLANG)" \
> +		BPF_CFLAGS="$(BPF_CFLAGS) $(CLANG_CFLAGS)" \
> +		BPF_TARGET_ENDIAN="$(BPF_TARGET_ENDIAN)" \
> +		Q="$(Q)"
> +
> +LIBARENA_BPF_DEPS := $(wildcard libarena/Makefile		\
> +				 libarena/include/*		\
> +				 libarena/src/*			\
> +				 libarena/selftests/*		\
> +				 libarena/*.bpf.o)
> +
> +LIBARENA_SKEL := libarena/libarena.skel.h
> +
> +$(LIBARENA_SKEL): $(INCLUDE_DIR)/vmlinux.h $(BPFOBJ) $(LIBARENA_BPF_DEPS)
> +	+$(MAKE) -C libarena libarena.skel.h $(LIBARENA_MAKE_ARGS)
> +
>  # Define test_progs test runner.
>  TRUNNER_TESTS_DIR := prog_tests
>  TRUNNER_BPF_PROGS_DIR := progs
> @@ -931,3 +955,6 @@ override define INSTALL_RULE
>  		rsync -a $(OUTPUT)/$$DIR/*.bpf.o $(INSTALL_PATH)/$$DIR;\
>  	done
>  endef
> +
> +test_libarena: $(INCLUDE_DIR)/vmlinux.h $(BPFOBJ)
> +	+$(MAKE) -C libarena $@ $(LIBARENA_MAKE_ARGS)
> diff --git a/tools/testing/selftests/bpf/libarena/Makefile b/tools/testing/selftests/bpf/libarena/Makefile
> new file mode 100644
> index 000000000000..304197e8a22f
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/libarena/Makefile
> @@ -0,0 +1,75 @@
> +# SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
> +# Copyright (c) 2026 Meta Platforms, Inc. and affiliates.
> +
> +.PHONY: clean
> +
> +# Defaults for standalone builds
> +
> +CLANG ?= clang
> +BPFTOOL ?= bpftool
> +LDLIBS ?= -lbpf -lelf -lz -lrt -lpthread -lzstd
> +
> +ifeq ($(V),1)
> +Q =
> +msg =
> +else
> +Q ?= @
> +msg = @printf '  %-8s%s %s%s\n' "$(1)" "$(if $(2), [$(2)])" "$(notdir $(3))" "$(if $(4), $(4))";
> +endif
> +
> +IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \
> +			grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__')
> +BPF_TARGET_ENDIAN ?= $(if $(IS_LITTLE_ENDIAN),--target=bpfel,--target=bpfeb)
> +
> +LIBARENA=$(abspath .)
> +BPFDIR=$(abspath $(LIBARENA)/..)
> +
> +INCLUDE_DIR ?= $(BPFDIR)/tools/include
> +LIBBPF_INCLUDE ?= $(INCLUDE_DIR)
> +
> +# Scan src/ and selftests/ to generate the final binaries
> +LIBARENA_SOURCES = $(wildcard $(LIBARENA)/src/*.bpf.c) $(wildcard $(LIBARENA)/selftests/*.bpf.c)
> +LIBARENA_OBJECTS = $(notdir $(LIBARENA_SOURCES:.bpf.c=.bpf.o))
> +
> +INCLUDES = -I$(LIBARENA)/include -I$(BPFDIR)
> +ifneq ($(INCLUDE_DIR),)
> +INCLUDES += -I$(INCLUDE_DIR)
> +endif
> +ifneq ($(LIBBPF_INCLUDE),)
> +INCLUDES += -I$(LIBBPF_INCLUDE)
> +endif
> +
> +# ENABLE_ATOMICS_TESTS required because we use arena spinlocks
> +override BPF_CFLAGS += -DENABLE_ATOMICS_TESTS
> +override BPF_CFLAGS += -O2 -g
> +override BPF_CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers
> +# Required for suppressing harmless vmlinux.h-related warnings.
> +override BPF_CFLAGS += -Wno-missing-declarations
> +override BPF_CFLAGS += $(INCLUDES)
> +
> +CFLAGS = -O2 -no-pie
> +CFLAGS += $(INCLUDES)
> +
> +vpath %.bpf.c $(LIBARENA)/src $(LIBARENA)/selftests
> +vpath %.c $(LIBARENA)/src $(LIBARENA)/selftests
> +
> +all: test_libarena
> +
> +test_libarena: selftest.c $(BPFOBJ) libarena.skel.h
> +	$(call msg,BINARY,libarena,$@)
> +	$(Q)$(CLANG) $(CFLAGS) $< $(BPFOBJ) $(LDLIBS) -o $@
> +
> +libarena.skel.h: libarena.bpf.o
> +	$(call msg,GEN-SKEL,libarena,$@)
> +	$(Q)$(BPFTOOL) gen skeleton $< name "libarena" > $@
> +
> +libarena.bpf.o: $(LIBARENA_OBJECTS)
> +	$(call msg,GEN-OBJ,libarena,$@)
> +	$(Q)$(BPFTOOL) gen object $@ $^
> +
> +%.bpf.o: %.bpf.c
> +	$(call msg,CLNG-BPF,libarena,$@)
> +	$(Q)$(CLANG) $(BPF_CFLAGS) $(BPF_TARGET_ENDIAN) -c $< -o $@
> +
> +clean:
> +	$(Q)rm -f *.skel.h *.bpf.o test_libarena
> diff --git a/tools/testing/selftests/bpf/libarena/include/common.h b/tools/testing/selftests/bpf/libarena/include/common.h
> new file mode 100644
> index 000000000000..338a5b4b19e4
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/libarena/include/common.h
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
> +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
> +#pragma once
> +
> +#ifdef __BPF__
> +
> +#include <vmlinux.h>
> +
> +#include "../../bpf_arena_common.h"
> +#include "../../progs/bpf_arena_spin_lock.h"
> +
> +#include <asm-generic/errno.h>
> +
> +#ifndef __BPF_FEATURE_ADDR_SPACE_CAST
> +#error "Arena allocators require bpf_addr_space_cast feature"
> +#endif
> +
> +#define arena_stdout(fmt, ...) bpf_stream_printk(1, (fmt), ##__VA_ARGS__)
> +#define arena_stderr(fmt, ...) bpf_stream_printk(2, (fmt), ##__VA_ARGS__)
> +
> +#ifndef __maybe_unused
> +#define __maybe_unused __attribute__((__unused__))
> +#endif
> +
> +#define private(name) SEC(".data." #name) __hidden __attribute__((aligned(8)))
> +
> +#define ARENA_PAGES (1UL << (32 - __builtin_ffs(__PAGE_SIZE) + 1))
> +
> +struct {
> +	__uint(type, BPF_MAP_TYPE_ARENA);
> +	__uint(map_flags, BPF_F_MMAPABLE);
> +	__uint(max_entries, ARENA_PAGES); /* number of pages */
> +#if defined(__TARGET_ARCH_arm64) || defined(__aarch64__)
> +	__ulong(map_extra, (1ull << 32)); /* start of mmap() region */
> +#else
> +	__ulong(map_extra, (1ull << 44)); /* start of mmap() region */
> +#endif
> +} arena __weak SEC(".maps");
> +
> +extern const volatile u32 zero;

Within subsequent patches you're using this zero variable to
initialize loop index variables. I assume this is to prevent the
compiler from over-optimizing (e.g., unrolling the loops) by forcing a
load from memory? If so, perhaps a comment is warranted? Someone may
naively come along and swap this out with a literal, and that may
intentionally not be the semantic we want here.

> +int arena_fls(__u64 word);
> +
> +#else /* ! __BPF__ */
> +
> +#include <stdint.h>
> +
> +#define __arena
> +
> +typedef uint8_t u8;
> +typedef uint16_t u16;
> +typedef uint32_t u32;
> +typedef uint64_t u64;
> +typedef int8_t s8;
> +typedef int16_t s16;
> +typedef int32_t s32;
> +typedef int64_t s64;
> +
> +/* Dummy "definition" for userspace. */
> +#define arena_spinlock_t int
> +
> +#endif /* __BPF__ */
> +
> +struct arena_get_base_args {
> +	void __arena *arena_base;
> +};
> diff --git a/tools/testing/selftests/bpf/libarena/include/selftest_helpers.h b/tools/testing/selftests/bpf/libarena/include/selftest_helpers.h
> new file mode 100644
> index 000000000000..92e580ea80de
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/libarena/include/selftest_helpers.h
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
> +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
> +#pragma once
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <sys/mman.h>
> +
> +#include <bpf/libbpf.h>
> +#include <bpf/bpf.h>
> +
> +static inline int libarena_run_prog(int prog_fd)
> +{
> +	LIBBPF_OPTS(bpf_test_run_opts, opts);
> +	int ret;
> +
> +	ret = bpf_prog_test_run_opts(prog_fd, &opts);
> +	if (ret)
> +		return ret;
> +
> +	return opts.retval;
> +}
> +
> +static inline bool libarena_is_test_prog(const char *name)
> +{
> +	return strstr(name, "test_") == name;
> +}
> +
> +static inline int libarena_run_prog_args(int prog_fd, void *args, size_t argsize)
> +{
> +	LIBBPF_OPTS(bpf_test_run_opts, opts);
> +	int ret;
> +
> +	opts.ctx_in = args;
> +	opts.ctx_size_in = argsize;
> +
> +	ret = bpf_prog_test_run_opts(prog_fd, &opts);
> +
> +	return ret ?: opts.retval;
> +}
> +
> +static inline int libarena_get_arena_base(int arena_get_base_fd,
> +					  void **arena_base)
> +{
> +	LIBBPF_OPTS(bpf_test_run_opts, opts);
> +	struct arena_get_base_args args = { .arena_base = NULL };
> +	int ret;
> +
> +	opts.ctx_in = &args;
> +	opts.ctx_size_in = sizeof(args);
> +
> +	ret = bpf_prog_test_run_opts(arena_get_base_fd, &opts);
> +	if (ret)
> +		return ret;
> +	if (opts.retval)
> +		return opts.retval;
> +
> +	*arena_base = args.arena_base;
> +	return 0;
> +}
> +
> +static inline int libarena_get_globals_pages(int arena_get_base_fd,
> +					     size_t arena_all_pages,
> +					     u64 *globals_pages)
> +{
> +	size_t pgsize = sysconf(_SC_PAGESIZE);
> +	void *arena_base;
> +	ssize_t i;
> +	u8 *vec;
> +	int ret;
> +
> +	ret = libarena_get_arena_base(arena_get_base_fd, &arena_base);
> +	if (ret)
> +		return ret;
> +
> +	if (!arena_base)
> +		return -EINVAL;
> +
> +	vec = calloc(arena_all_pages, sizeof(*vec));
> +	if (!vec)
> +		return -ENOMEM;
> +
> +	if (mincore(arena_base, arena_all_pages * pgsize, vec) < 0) {
> +		ret = -errno;
> +		free(vec);
> +		return ret;
> +	}
> +
> +	*globals_pages = 0;
> +	for (i = arena_all_pages - 1; i >= 0; i--) {
> +		if (!(vec[i] & 0x1))
> +			break;
> +		*globals_pages += 1;
> +	}
> +
> +	free(vec);
> +	return 0;
> +}
> diff --git a/tools/testing/selftests/bpf/libarena/selftests/selftest.c b/tools/testing/selftests/bpf/libarena/selftests/selftest.c
> new file mode 100644
> index 000000000000..bd4794be18fc
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/libarena/selftests/selftest.c
> @@ -0,0 +1,160 @@
> +// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
> +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
> +
> +#define _GNU_SOURCE
> +#include <assert.h>
> +#include <errno.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#include <bpf/libbpf.h>
> +#include <bpf/bpf.h>
> +
> +#include <sys/mman.h>
> +#include <sys/resource.h>
> +#include <sys/sysinfo.h>
> +
> +#include <common.h>
> +#include <selftest_helpers.h>
> +
> +struct arena_qnode {
> +	unsigned long next;
> +	int count;
> +	int locked;
> +};
> +
> +#include "../libarena.skel.h"
> +typedef struct libarena selftest;
> +#define selftest__open libarena__open
> +#define selftest__open_and_load libarena__open_and_load
> +#define selftest__load libarena__load
> +#define selftest__attach libarena__attach
> +#define selftest__destroy libarena__destroy
> +
> +static bool verbose;
> +static int testno = 1;
> +
> +static int
> +run_prog_verbose(int prog_fd)
> +{
> +	char buf[1024];
> +	int ret, err;
> +
> +	ret = libarena_run_prog(prog_fd);
> +
> +	if (ret)
> +		fprintf(stderr, "error %d in %s\n", ret, __func__);
> +
> +	if (verbose) {
> +		printf("BPF stdout:\n");
> +		while ((err = bpf_prog_stream_read(prog_fd, 1, buf, 1024, NULL)) > 0)
> +			printf("%.*s", err, buf);
> +
> +		if (err)
> +			return err;
> +
> +		printf("BPF stderr:\n");
> +		while ((err = bpf_prog_stream_read(prog_fd, 2, buf, 1024, NULL)) > 0)
> +			printf("%.*s", err, buf);
> +
> +		if (err)
> +			return err;
> +	}
> +
> +	return ret;
> +}
> +
> +static int libbpf_print_fn(enum libbpf_print_level level,
> +		const char *format, va_list args)
> +{
> +	if (level == LIBBPF_DEBUG)
> +		return 0;
> +	return vfprintf(stderr, format, args);
> +}
> +
> +static int run_test(selftest *skel, struct bpf_program *prog)
> +{
> +	int prog_fd;
> +
> +	prog_fd = bpf_program__fd(prog);
> +	if (prog_fd < 0)
> +		return prog_fd;
> +
> +	return run_prog_verbose(prog_fd);
> +}
> +
> +static void
> +banner(const char *progpath)
> +{
> +	char *name = basename(progpath);
> +
> +	printf("%s\n", name);
> +
> +	printf("=== %s ===\n", "libarena selftests");
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +	struct bpf_program *prog;
> +	selftest *skel;
> +	int err = 0;
> +	int ret;
> +
> +	banner(argv[0]);
> +
> +	for (int i = 1; i < argc; i++) {
> +		if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
> +			verbose = true;
> +			continue;
> +		}
> +
> +		fprintf(stderr, "usage: ./%s [-v] [--verbose]\n", argv[0]);
> +		fprintf(stderr, "verbose option prints out BPF streams,"
> +				" including ASAN stacks when applicable\n");
> +
> +		return -EINVAL;
> +	}
> +
> +	libbpf_set_print(libbpf_print_fn);
> +
> +	skel = selftest__open_and_load();
> +	if (!skel) {
> +		fprintf(stderr, "Failed to open and load skeleton\n");
> +		return 1;
> +	}
> +
> +	ret = selftest__attach(skel);
> +	if (ret) {
> +		fprintf(stderr, "Failed to attach skeleton\n");
> +		selftest__destroy(skel);
> +		return 1;
> +	}
> +
> +	ret = libarena_run_prog(bpf_program__fd(skel->progs.arena_alloc_reserve));
> +	if (ret) {
> +		fprintf(stderr, "Failed to initialize arena: %d\n", ret);
> +		selftest__destroy(skel);
> +		return 1;
> +	}
> +
> +	bpf_object__for_each_program(prog, skel->obj) {
> +		const char *name = bpf_program__name(prog);
> +
> +		if (!libarena_is_test_prog(name))
> +			continue;
> +
> +		ret = run_test(skel, prog);
> +		if (ret)
> +			printf("not ok %d - %s\n", testno++, name);
> +		else
> +			printf("ok %d - %s\n", testno++, name);
> +
> +		if (ret)
> +			err = -EINVAL;
> +	}
> +
> +	selftest__destroy(skel);
> +
> +	return err;
> +}
> diff --git a/tools/testing/selftests/bpf/libarena/src/common.bpf.c b/tools/testing/selftests/bpf/libarena/src/common.bpf.c
> new file mode 100644
> index 000000000000..db6dd8a011ae
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/libarena/src/common.bpf.c
> @@ -0,0 +1,62 @@
> +// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
> +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
> +#include <common.h>
> +
> +const volatile u32 zero = 0;
> +
> +/* How many pages do we reserve at the beginning of the arena segment? */
> +#define RESERVE_ALLOC (8)
> +
> +int arena_fls(__u64 word)
> +{
> +	unsigned int num = 0;
> +
> +	if (!word)
> +		return 0;
> +
> +	if (word & 0xffffffff00000000ULL) {
> +		num += 32;
> +		word >>= 32;
> +	}
> +
> +	if (word & 0xffff0000) {
> +		num += 16;
> +		word >>= 16;
> +	}
> +
> +	if (word & 0xff00) {
> +		num += 8;
> +		word >>= 8;
> +	}
> +
> +	if (word & 0xf0) {
> +		num += 4;
> +		word >>= 4;
> +	}
> +
> +	if (word & 0xc) {
> +		num += 2;
> +		word >>= 2;
> +	}
> +
> +	if (word & 0x2)
> +		num += 1;
> +
> +	return num + 1;
> +}

What's your reason for not using something like __builtin_clzll()
instead here, for example:

int arena_fls(u64 word)
{
	if (!word)
		return 0;

	return 64 - __builtin_clzll(word);
}

I imagine that you've implemented it in this open-coded way for either
verifier predicatability or toolchain portability reasons? The latter
has no practical significance IMO given that you're already reliant on
predefined toolchain preprocessor macros like
__BPF_FEATURE_ADDR_SPACE_CAST anyway.

> +SEC("syscall")
> +__weak int arena_get_base(struct arena_get_base_args *args)
> +{
> +	args->arena_base = arena_base(&arena);
> +
> +	return 0;
> +}

Just an idea bu perhaps this kind of SYSCALL helper BPF program should
be named arena_get_info() and take a struct arena_get_info_ctx
argument instead? I think it'll make it more future proof. If we want
to expose more details from the BPF arena in the future (e.g., total
size, number of active pages, etc), we wouldn't need to create new
SYSCALL helper BPF programs or break the existing signature. We can
use a struct with a size field or reserved fields for future use.

> +SEC("syscall")
> +__weak int arena_alloc_reserve(void)
> +{
> +	return bpf_arena_reserve_pages(&arena, NULL, RESERVE_ALLOC);
> +}

What do you think about this SYSCALL helper BPF program taking a
context argument which would allow userspace to define the number of
pages that should be reserved? This would make things slightly more
flexible and resuable?


  parent reply	other threads:[~2026-04-23  8:24 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-21 16:50 [PATCH bpf-next v8 0/8] Introduce arena library and runtime Emil Tsalapatis
2026-04-21 16:50 ` [PATCH bpf-next v8 1/8] selftests/bpf: Add ifdef guard for WRITE_ONCE macro in bpf_atomic.h Emil Tsalapatis
2026-04-23  8:27   ` Matt Bobrowski
2026-04-21 16:50 ` [PATCH bpf-next v8 2/8] selftests/bpf: Add basic libarena scaffolding Emil Tsalapatis
2026-04-21 20:08   ` sashiko-bot
2026-04-23  8:24   ` Matt Bobrowski [this message]
2026-04-21 16:50 ` [PATCH bpf-next v8 3/8] selftests/bpf: Move arena-related headers into libarena Emil Tsalapatis
2026-04-21 16:50 ` [PATCH bpf-next v8 4/8] selftests/bpf: Add arena ASAN runtime to libarena Emil Tsalapatis
2026-04-21 20:48   ` sashiko-bot
2026-04-21 16:50 ` [PATCH bpf-next v8 5/8] selftests/bpf: Add ASAN support for libarena selftests Emil Tsalapatis
2026-04-21 21:15   ` sashiko-bot
2026-04-21 16:50 ` [PATCH bpf-next v8 6/8] selftests/bpf: Add buddy allocator for libarena Emil Tsalapatis
2026-04-21 17:52   ` bot+bpf-ci
2026-04-21 17:56     ` Emil Tsalapatis
2026-04-21 21:42   ` sashiko-bot
2026-04-23  8:44   ` Matt Bobrowski
2026-04-21 16:50 ` [PATCH bpf-next v8 7/8] selftests/bpf: Add selftests for libarena buddy allocator Emil Tsalapatis
2026-04-21 21:57   ` sashiko-bot
2026-04-21 16:50 ` [PATCH bpf-next v8 8/8] selftests/bpf: Reuse stderr parsing for libarena ASAN tests Emil Tsalapatis
2026-04-21 22:16   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aenXSvDSN98azW_T@google.com \
    --to=mattbobrowski@google.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=memxor@gmail.com \
    --cc=song@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox