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 2/6] selftests/bpf: libarena: Inline nonatomic bitmap operations
Date: Mon, 17 Aug 2026 15:16:12 -0400 [thread overview]
Message-ID: <20260817191616.11071-3-emil@etsalapatis.com> (raw)
In-Reply-To: <20260817191616.11071-1-emil@etsalapatis.com>
The libarena code currently defines the non-atomic bitmap set/get
operations as __weak functions, in accordance with the libarena
coding style. This, however, is significant overhead to call
functions that span single-digit instructions.
Make an exception and expose the getters/setters as static inline
functions in the header. Since the function body is now inlined
into the caller, mark reads/writes with READ_ONCE()/WRITE_ONCE()
to prevent compiler optimizations from breaking code that locklessly
polls the bitmap.
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
---
.../bpf/libarena/include/libarena/bitmap.h | 29 +++++++++++++++++--
.../selftests/bpf/libarena/src/bitmap.bpf.c | 18 ------------
2 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/tools/testing/selftests/bpf/libarena/include/libarena/bitmap.h b/tools/testing/selftests/bpf/libarena/include/libarena/bitmap.h
index 8c5936ae9958..163e2b83d943 100644
--- a/tools/testing/selftests/bpf/libarena/include/libarena/bitmap.h
+++ b/tools/testing/selftests/bpf/libarena/include/libarena/bitmap.h
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
#pragma once
+#include <bpf_atomic.h>
+
#define BITS_PER_BYTE 8
#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_BYTE)
@@ -16,11 +18,8 @@ struct arena_bitmap {
struct arena_bitmap __arena *bmp_alloc(size_t bits);
void bmp_free(struct arena_bitmap __arena *bmp);
-void __bmp_set_bit(u32 bit, struct arena_bitmap __arena *bmp);
-void __bmp_clear_bit(u32 bit, struct arena_bitmap __arena *bmp);
void bmp_set_bit(u32 bit, struct arena_bitmap __arena *bmp);
void bmp_clear_bit(u32 bit, struct arena_bitmap __arena *bmp);
-bool bmp_test_bit(u32 bit, struct arena_bitmap __arena *bmp);
bool bmp_test_and_clear_bit(u32 bit, struct arena_bitmap __arena *bmp);
bool bmp_test_and_set_bit(u32 bit, struct arena_bitmap __arena *bmp);
@@ -33,3 +32,27 @@ void bmp_copy(size_t bits, struct arena_bitmap __arena *dst, struct arena_bitmap
bool bmp_intersects(size_t bits, struct arena_bitmap __arena *arg1, struct arena_bitmap __arena *arg2);
bool bmp_subset(size_t bits, struct arena_bitmap __arena *big, struct arena_bitmap __arena *small);
void bmp_print(size_t bits, struct arena_bitmap __arena *bmp);
+
+static __always_inline
+void __bmp_set_bit(u32 bit, struct arena_bitmap __arena *bmp)
+{
+ volatile u64 __arena *word = &bmp->bits[BIT_WORD(bit)];
+
+ *word |= BIT_MASK(bit);
+}
+
+static __always_inline
+void __bmp_clear_bit(u32 bit, struct arena_bitmap __arena *bmp)
+{
+ volatile u64 __arena *word = &bmp->bits[BIT_WORD(bit)];
+
+ *word &= ~BIT_MASK(bit);
+}
+
+static __always_inline
+bool bmp_test_bit(u32 bit, struct arena_bitmap __arena *bmp)
+{
+ u64 word = READ_ONCE(bmp->bits[BIT_WORD(bit)]);
+
+ return word & BIT_MASK(bit);
+}
diff --git a/tools/testing/selftests/bpf/libarena/src/bitmap.bpf.c b/tools/testing/selftests/bpf/libarena/src/bitmap.bpf.c
index 5ff8e688ddc7..0390f20ce366 100644
--- a/tools/testing/selftests/bpf/libarena/src/bitmap.bpf.c
+++ b/tools/testing/selftests/bpf/libarena/src/bitmap.bpf.c
@@ -34,24 +34,6 @@ void bmp_free(struct arena_bitmap __arena *bmp)
arena_free(bmp);
}
-__weak
-void __bmp_set_bit(u32 bit, struct arena_bitmap __arena *bmp)
-{
- bmp->bits[BIT_WORD(bit)] |= BIT_MASK(bit);
-}
-
-__weak
-void __bmp_clear_bit(u32 bit, struct arena_bitmap __arena *bmp)
-{
- bmp->bits[BIT_WORD(bit)] &= ~BIT_MASK(bit);
-}
-
-__weak
-bool bmp_test_bit(u32 bit, struct arena_bitmap __arena *bmp)
-{
- return bmp->bits[BIT_WORD(bit)] & BIT_MASK(bit);
-}
-
__weak
bool bmp_test_and_clear_bit(u32 bit, struct arena_bitmap __arena *bmp)
{
--
2.54.0
next prev 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 ` Emil Tsalapatis [this message]
2026-08-17 19:26 ` [PATCH 2/6] selftests/bpf: libarena: Inline nonatomic bitmap operations 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 ` [PATCH 4/6] selftests/bpf: libarena: Add calloc() call Emil Tsalapatis
2026-08-17 19:23 ` 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-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox