All of lore.kernel.org
 help / color / mirror / Atom feed
From: Emil Tsalapatis <emil@etsalapatis.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, memxor@gmail.com,
	daniel@iogearbox.net, eddyz87@gmail.com,
	Emil Tsalapatis <emil@etsalapatis.com>
Subject: [PATCH 4/6] selftests/bpf: libarena: Add calloc() call
Date: Mon, 17 Aug 2026 15:16:14 -0400	[thread overview]
Message-ID: <20260817191616.11071-5-emil@etsalapatis.com> (raw)
In-Reply-To: <20260817191616.11071-1-emil@etsalapatis.com>

The arena memory allocator currently does not provide the
option to zero-initialize the allocated memory. Provide
a calloc() operation that calls memset() on the returned
memory. Reuse naive memset implementation already present
in the arena ASAN code for now. Subsequent patches will
optimize the function.

Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
---
 .../bpf/libarena/include/libarena/common.h    | 18 +++++++++++++
 .../selftests/bpf/libarena/src/asan.bpf.c     | 21 ++-------------
 .../selftests/bpf/libarena/src/common.bpf.c   | 27 ++++++++++++++++++-
 3 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/bpf/libarena/include/libarena/common.h b/tools/testing/selftests/bpf/libarena/include/libarena/common.h
index 931ace9a49e2..d32a51ff5e7f 100644
--- a/tools/testing/selftests/bpf/libarena/include/libarena/common.h
+++ b/tools/testing/selftests/bpf/libarena/include/libarena/common.h
@@ -49,6 +49,7 @@ extern volatile u64 asan_violated;
 int arena_fls(__u64 word);
 
 void __arena *arena_malloc(size_t size);
+void __arena *arena_calloc(size_t ncount, size_t size);
 void arena_free(void __arena *ptr);
 
 /*
@@ -61,6 +62,23 @@ void arena_free(void __arena *ptr);
  */
 #define arena_subprog_init() do { asm volatile ("" :: "r"(&arena)); } while (0)
 
+/*
+ * BPF does not currently support the memset intrinsics. for large
+ * sequential copies, or assignments of large data structures,
+ * the frontend will generate an intrinsic that causes the BPF
+ * backend to exit due to a missing implementation. Provide
+ * implementations for the intrinsic.
+ */
+static inline int arena_memset(s8 __arena *dst, s8 val, size_t size)
+{
+	size_t i;
+
+	for (i = zero; i < size && can_loop; i++)
+		dst[i] = val;
+
+	return 0;
+}
+
 #else /* ! __BPF__ */
 
 #include <stdint.h>
diff --git a/tools/testing/selftests/bpf/libarena/src/asan.bpf.c b/tools/testing/selftests/bpf/libarena/src/asan.bpf.c
index 5135d5c72a46..de656b69d13a 100644
--- a/tools/testing/selftests/bpf/libarena/src/asan.bpf.c
+++ b/tools/testing/selftests/bpf/libarena/src/asan.bpf.c
@@ -103,23 +103,6 @@ volatile bool asan_inited = false;
  */
 volatile bool asan_report_once = false;
 
-/*
- * BPF does not currently support the memset/memcpy/memcmp intrinsics.
- * For large sequential copies, or assignments of large data structures,
- * the frontend will generate an intrinsic that causes the BPF backend
- * to exit due to a missing implementation. Provide a simple implementation
- * just for memset to use it for poisoning/unpoisoning the map.
- */
-__weak int asan_memset(s8 __arena *dst, s8 val, size_t size)
-{
-	size_t i;
-
-	for (i = zero; i < size && can_loop; i++)
-		dst[i] = val;
-
-	return 0;
-}
-
 /* Validate a 1-byte access, always within a single byte. */
 static __always_inline bool memory_is_poisoned_1(s8 __arena *addr)
 {
@@ -422,7 +405,7 @@ __hidden __noasan int asan_poison(void __arena *addr, s8 val, size_t size)
 	shadow = mem_to_shadow(addr);
 	len = size >> ASAN_SHADOW_SHIFT;
 
-	asan_memset(shadow, val, len);
+	arena_memset(shadow, val, len);
 
 	return 0;
 }
@@ -463,7 +446,7 @@ __hidden __noasan int asan_unpoison(void __arena *addr, size_t size)
 	shadow = mem_to_shadow(addr);
 	len = size >> ASAN_SHADOW_SHIFT;
 
-	asan_memset(shadow, 0, len);
+	arena_memset(shadow, 0, len);
 
 	/*
 	 * If we are allocating a non-granule aligned region, we need to adjust
diff --git a/tools/testing/selftests/bpf/libarena/src/common.bpf.c b/tools/testing/selftests/bpf/libarena/src/common.bpf.c
index 569f0f64d518..785d4872cb49 100644
--- a/tools/testing/selftests/bpf/libarena/src/common.bpf.c
+++ b/tools/testing/selftests/bpf/libarena/src/common.bpf.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+#include <limits.h>
+
 #include <libarena/common.h>
 #include <libarena/asan.h>
 #include <libarena/buddy.h>
@@ -48,10 +50,33 @@ __weak void __arena *arena_malloc(size_t size)
 	return buddy_alloc(&buddy, size);
 }
 
+__weak void __arena *arena_calloc(size_t ncount, size_t size)
+{
+	void __arena *mem;
+	size_t total;
+
+	/*
+	 * Ideally we'd be using __builtin_mul_overflow here,
+	 * but the BPF compiler backend doesn't implement __multi3.
+	 * There are ways to optimize the division away from the
+	 * overflow check, but any costs are dwarfed by the
+	 * buddy_alloc() call. Keep it simple for now.
+	 */
+	if (unlikely(ncount && size >= ULLONG_MAX / ncount))
+		return NULL;
+
+	total = ncount * size;
+
+	mem = buddy_alloc(&buddy, total);
+	if (likely(mem))
+		arena_memset(mem, 0, total);
+
+	return mem;
+}
+
 __weak void arena_free(void __arena *ptr)
 {
 	buddy_free(&buddy, ptr);
 }
 
-
 char _license[] SEC("license") = "GPL";
-- 
2.54.0


  parent reply	other threads:[~2026-08-17 19:16 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-17 19:16 [PATCH 0/6] selftests/bpf: Fixes and improvements for libarena Emil Tsalapatis
2026-08-17 19:16 ` [PATCH 1/6] selftests/bpf: libarena: Normalize SPDX headers across files Emil Tsalapatis
2026-08-17 19:21   ` sashiko-bot
2026-08-17 19:16 ` [PATCH 2/6] selftests/bpf: libarena: Inline nonatomic bitmap operations Emil Tsalapatis
2026-08-17 19:26   ` sashiko-bot
2026-08-17 20:25   ` bot+bpf-ci
2026-08-17 19:16 ` [PATCH 3/6] selftests/bpf: libarena: Disable IRQs during allocation Emil Tsalapatis
2026-08-17 19:28   ` sashiko-bot
2026-08-17 20:38   ` bot+bpf-ci
2026-08-17 19:16 ` Emil Tsalapatis [this message]
2026-08-17 19:23   ` [PATCH 4/6] selftests/bpf: libarena: Add calloc() call sashiko-bot
2026-08-17 20:25   ` bot+bpf-ci
2026-08-17 19:16 ` [PATCH 5/6] selftests/bpf: libarena: Add a benchmark for malloc()/calloc() Emil Tsalapatis
2026-08-17 19:31   ` sashiko-bot
2026-08-17 20:25   ` bot+bpf-ci
2026-08-17 19:16 ` [PATCH 6/6] selftests/bpf: libarena: Optimize and make public arena_memset Emil Tsalapatis
2026-08-17 20:25   ` bot+bpf-ci

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=20260817191616.11071-5-emil@etsalapatis.com \
    --to=emil@etsalapatis.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=memxor@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.