[PATCH 2/6] selftests/bpf: libarena: Inline nonatomic bitmap operations

Emil Tsalapatis <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <[email protected]>
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 <[email protected]>
---
 .../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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.