libbpf: Provide barrier() and barrier_var() in bpf_helpers.h
authorAndrii Nakryiko <andrii@kernel.org>
Mon, 9 May 2022 00:41:46 +0000 (17:41 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 9 May 2022 15:15:32 +0000 (17:15 +0200)
Add barrier() and barrier_var() macros into bpf_helpers.h to be used by
end users. While a bit advanced and specialized instruments, they are
sometimes indispensable. Instead of requiring each user to figure out
exact asm volatile incantations for themselves, provide them from
bpf_helpers.h.

Also remove conflicting definitions from selftests. Some tests rely on
barrier_var() definition being nothing, those will still work as libbpf
does the #ifndef/#endif guarding for barrier() and barrier_var(),
allowing users to redefine them, if necessary.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20220509004148.1801791-8-andrii@kernel.org
tools/lib/bpf/bpf_helpers.h
tools/testing/selftests/bpf/progs/exhandler_kern.c
tools/testing/selftests/bpf/progs/loop5.c
tools/testing/selftests/bpf/progs/profiler1.c
tools/testing/selftests/bpf/progs/pyperf.h
tools/testing/selftests/bpf/progs/test_pkt_access.c

index bbae9a057bc877242ed766aa82a9ccbdad405ff8..fb04eaf367f1713f1e4b653e6c9ad883926eb598 100644 (file)
        })
 #endif
 
+/*
+ * Compiler (optimization) barrier.
+ */
+#ifndef barrier
+#define barrier() asm volatile("" ::: "memory")
+#endif
+
+/* Variable-specific compiler (optimization) barrier. It's a no-op which makes
+ * compiler believe that there is some black box modification of a given
+ * variable and thus prevents compiler from making extra assumption about its
+ * value and potential simplifications and optimizations on this variable.
+ *
+ * E.g., compiler might often delay or even omit 32-bit to 64-bit casting of
+ * a variable, making some code patterns unverifiable. Putting barrier_var()
+ * in place will ensure that cast is performed before the barrier_var()
+ * invocation, because compiler has to pessimistically assume that embedded
+ * asm section might perform some extra operations on that variable.
+ *
+ * This is a variable-specific variant of more global barrier().
+ */
+#ifndef barrier_var
+#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var))
+#endif
+
 /*
  * Helper macro to throw a compilation error if __bpf_unreachable() gets
  * built into the resulting code. This works given BPF back end does not
index dd9b30a0f0fc3bd44f1521c3af16b59aa4e402d6..20d009e2d266c7b3a741a14c96d899cf153e11c8 100644 (file)
@@ -7,8 +7,6 @@
 #include <bpf/bpf_tracing.h>
 #include <bpf/bpf_core_read.h>
 
-#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var))
-
 char _license[] SEC("license") = "GPL";
 
 unsigned int exception_triggered;
index 913791923fa3249b584611e2e69628811bc1beeb..1b13f37f85ec052970f1b2160a55ea0b0f78695f 100644 (file)
@@ -2,7 +2,6 @@
 // Copyright (c) 2019 Facebook
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
-#define barrier() __asm__ __volatile__("": : :"memory")
 
 char _license[] SEC("license") = "GPL";
 
index 4df9088bfc0037a717d6e3a11fb375ea31daa62a..fb6b1352294936cf34ac011425869b09aa8b70b1 100644 (file)
@@ -1,6 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2020 Facebook */
-#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var))
 #define UNROLL
 #define INLINE __always_inline
 #include "profiler.inc.h"
index 5d3dc4d66d471b09b46b088d29a1a9080174d0f1..6c7b1fb268d63fd02f2172fbb87dee93b84d7c13 100644 (file)
@@ -171,8 +171,6 @@ struct process_frame_ctx {
        bool done;
 };
 
-#define barrier_var(var) asm volatile("" : "=r"(var) : "0"(var))
-
 static int process_frame_callback(__u32 i, struct process_frame_ctx *ctx)
 {
        int zero = 0;
index 0558544e1ff0fb0749ba1668a99c06b4a1708d8e..5cd7c096f62d22e220217d95837b0a1f1effe29d 100644 (file)
@@ -14,8 +14,6 @@
 #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_endian.h>
 
-#define barrier() __asm__ __volatile__("": : :"memory")
-
 /* llvm will optimize both subprograms into exactly the same BPF assembly
  *
  * Disassembly of section .text: