diff options
author | Ilya Leoshkevich <iii@linux.ibm.com> | 2019-09-12 12:05:43 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-09-16 03:32:00 -0400 |
commit | 4ce150b6a412f14074400eac5fc39d1a71c4ef0a (patch) | |
tree | 121c913c2aadff0b9419c94ca58baa53bf4f3563 /tools | |
parent | a2c11b034142b9de9ab236aeeb53d6f39c3508aa (diff) |
selftests/bpf: add bpf-gcc support
Now that binutils and gcc support for BPF is upstream, make use of it in
BPF selftests using alu32-like approach. Share as much as possible of
CFLAGS calculation with clang.
Fixes only obvious issues, leaving more complex ones for later:
- Use gcc-provided bpf-helpers.h instead of manually defining the
helpers, change bpf_helpers.h include guard to avoid conflict.
- Include <linux/stddef.h> for __always_inline.
- Add $(OUTPUT)/../usr/include to include path in order to use local
kernel headers instead of system kernel headers when building with O=.
In order to activate the bpf-gcc support, one needs to configure
binutils and gcc with --target=bpf and make them available in $PATH. In
particular, gcc must be installed as `bpf-gcc`, which is the default.
Right now with binutils 25a2915e8dba and gcc r275589 only a handful of
tests work:
# ./test_progs_bpf_gcc
# Summary: 7/39 PASSED, 1 SKIPPED, 98 FAILED
The reason for those failures are as follows:
- Build errors:
- `error: too many function arguments for eBPF` for __always_inline
functions read_str_var and read_map_var - must be inlining issue,
and for process_l3_headers_v6, which relies on optimizing away
function arguments.
- `error: indirect call in function, which are not supported by eBPF`
where there are no obvious indirect calls in the source calls, e.g.
in __encap_ipip_none.
- `error: field 'lock' has incomplete type` for fields of `struct
bpf_spin_lock` type - bpf_spin_lock is re#defined by bpf-helpers.h,
so its usage is sensitive to order of #includes.
- `error: eBPF stack limit exceeded` in sysctl_tcp_mem.
- Load errors:
- Missing object files due to above build errors.
- `libbpf: failed to create map (name: 'test_ver.bss')`.
- `libbpf: object file doesn't contain bpf program`.
- `libbpf: Program '.text' contains unrecognized relo data pointing to
section 0`.
- `libbpf: BTF is required, but is missing or corrupted` - no BTF
support in gcc yet.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Cc: Jose E. Marchesi <jose.marchesi@oracle.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/bpf/Makefile | 65 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/bpf_helpers.h | 24 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/progs/test_tc_edt.c | 1 |
3 files changed, 67 insertions, 23 deletions
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 7f3196af1ae4..6889c19a628c 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile | |||
@@ -17,6 +17,7 @@ LLC ?= llc | |||
17 | LLVM_OBJCOPY ?= llvm-objcopy | 17 | LLVM_OBJCOPY ?= llvm-objcopy |
18 | LLVM_READELF ?= llvm-readelf | 18 | LLVM_READELF ?= llvm-readelf |
19 | BTF_PAHOLE ?= pahole | 19 | BTF_PAHOLE ?= pahole |
20 | BPF_GCC ?= $(shell command -v bpf-gcc;) | ||
20 | CFLAGS += -g -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(BPFDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include \ | 21 | CFLAGS += -g -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(BPFDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include \ |
21 | -Dbpf_prog_load=bpf_prog_test_load \ | 22 | -Dbpf_prog_load=bpf_prog_test_load \ |
22 | -Dbpf_load_program=bpf_test_load_program | 23 | -Dbpf_load_program=bpf_test_load_program |
@@ -46,6 +47,10 @@ ifneq ($(SUBREG_CODEGEN),) | |||
46 | TEST_GEN_FILES += $(patsubst %.o,alu32/%.o, $(BPF_OBJ_FILES)) | 47 | TEST_GEN_FILES += $(patsubst %.o,alu32/%.o, $(BPF_OBJ_FILES)) |
47 | endif | 48 | endif |
48 | 49 | ||
50 | ifneq ($(BPF_GCC),) | ||
51 | TEST_GEN_FILES += $(patsubst %.o,bpf_gcc/%.o, $(BPF_OBJ_FILES)) | ||
52 | endif | ||
53 | |||
49 | # Order correspond to 'make run_tests' order | 54 | # Order correspond to 'make run_tests' order |
50 | TEST_PROGS := test_kmod.sh \ | 55 | TEST_PROGS := test_kmod.sh \ |
51 | test_libbpf.sh \ | 56 | test_libbpf.sh \ |
@@ -137,16 +142,19 @@ endif | |||
137 | # | 142 | # |
138 | # Use '-idirafter': Don't interfere with include mechanics except where the | 143 | # Use '-idirafter': Don't interfere with include mechanics except where the |
139 | # build would have failed anyways. | 144 | # build would have failed anyways. |
140 | CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - </dev/null 2>&1 \ | 145 | define get_sys_includes |
146 | $(shell $(1) -v -E - </dev/null 2>&1 \ | ||
141 | | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') | 147 | | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') |
148 | endef | ||
149 | CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG)) | ||
150 | BPF_CFLAGS = -I. -I./include/uapi -I../../../include/uapi \ | ||
151 | -I$(OUTPUT)/../usr/include -D__TARGET_ARCH_$(SRCARCH) | ||
142 | 152 | ||
143 | CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \ | 153 | CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ |
144 | $(CLANG_SYS_INCLUDES) \ | 154 | -Wno-compare-distinct-pointer-types |
145 | -Wno-compare-distinct-pointer-types \ | ||
146 | -D__TARGET_ARCH_$(SRCARCH) | ||
147 | 155 | ||
148 | $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline | 156 | $(OUTPUT)/test_l4lb_noinline.o: BPF_CFLAGS += -fno-inline |
149 | $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline | 157 | $(OUTPUT)/test_xdp_noinline.o: BPF_CFLAGS += -fno-inline |
150 | 158 | ||
151 | $(OUTPUT)/test_queue_map.o: test_queue_stack_map.h | 159 | $(OUTPUT)/test_queue_map.o: test_queue_stack_map.h |
152 | $(OUTPUT)/test_stack_map.o: test_queue_stack_map.h | 160 | $(OUTPUT)/test_stack_map.o: test_queue_stack_map.h |
@@ -163,12 +171,12 @@ BTF_LLVM_PROBE := $(shell echo "int main() { return 0; }" | \ | |||
163 | /bin/rm -f ./llvm_btf_verify.o) | 171 | /bin/rm -f ./llvm_btf_verify.o) |
164 | 172 | ||
165 | ifneq ($(BTF_LLVM_PROBE),) | 173 | ifneq ($(BTF_LLVM_PROBE),) |
166 | CLANG_FLAGS += -g | 174 | BPF_CFLAGS += -g |
167 | else | 175 | else |
168 | ifneq ($(BTF_LLC_PROBE),) | 176 | ifneq ($(BTF_LLC_PROBE),) |
169 | ifneq ($(BTF_PAHOLE_PROBE),) | 177 | ifneq ($(BTF_PAHOLE_PROBE),) |
170 | ifneq ($(BTF_OBJCOPY_PROBE),) | 178 | ifneq ($(BTF_OBJCOPY_PROBE),) |
171 | CLANG_FLAGS += -g | 179 | BPF_CFLAGS += -g |
172 | LLC_FLAGS += -mattr=dwarfris | 180 | LLC_FLAGS += -mattr=dwarfris |
173 | DWARF2BTF = y | 181 | DWARF2BTF = y |
174 | endif | 182 | endif |
@@ -202,8 +210,8 @@ $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c | |||
202 | 210 | ||
203 | $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \ | 211 | $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \ |
204 | | $(ALU32_BUILD_DIR) | 212 | | $(ALU32_BUILD_DIR) |
205 | ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ | 213 | ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -target bpf -emit-llvm \ |
206 | echo "clang failed") | \ | 214 | -c $< -o - || echo "clang failed") | \ |
207 | $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ | 215 | $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ |
208 | -filetype=obj -o $@ | 216 | -filetype=obj -o $@ |
209 | ifeq ($(DWARF2BTF),y) | 217 | ifeq ($(DWARF2BTF),y) |
@@ -211,10 +219,37 @@ ifeq ($(DWARF2BTF),y) | |||
211 | endif | 219 | endif |
212 | endif | 220 | endif |
213 | 221 | ||
222 | ifneq ($(BPF_GCC),) | ||
223 | GCC_SYS_INCLUDES = $(call get_sys_includes,gcc) | ||
224 | IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \ | ||
225 | grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__') | ||
226 | ifeq ($(IS_LITTLE_ENDIAN),) | ||
227 | MENDIAN=-mbig-endian | ||
228 | else | ||
229 | MENDIAN=-mlittle-endian | ||
230 | endif | ||
231 | BPF_GCC_CFLAGS = $(GCC_SYS_INCLUDES) $(MENDIAN) | ||
232 | BPF_GCC_BUILD_DIR = $(OUTPUT)/bpf_gcc | ||
233 | TEST_CUSTOM_PROGS += $(BPF_GCC_BUILD_DIR)/test_progs_bpf_gcc | ||
234 | $(BPF_GCC_BUILD_DIR): | ||
235 | mkdir -p $@ | ||
236 | |||
237 | $(BPF_GCC_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read | $(BPF_GCC_BUILD_DIR) | ||
238 | cp $< $@ | ||
239 | |||
240 | $(BPF_GCC_BUILD_DIR)/test_progs_bpf_gcc: $(OUTPUT)/test_progs \ | ||
241 | | $(BPF_GCC_BUILD_DIR) | ||
242 | cp $< $@ | ||
243 | |||
244 | $(BPF_GCC_BUILD_DIR)/%.o: progs/%.c $(BPF_GCC_BUILD_DIR)/test_progs_bpf_gcc \ | ||
245 | | $(BPF_GCC_BUILD_DIR) | ||
246 | $(BPF_GCC) $(BPF_CFLAGS) $(BPF_GCC_CFLAGS) -O2 -c $< -o $@ | ||
247 | endif | ||
248 | |||
214 | # Have one program compiled without "-target bpf" to test whether libbpf loads | 249 | # Have one program compiled without "-target bpf" to test whether libbpf loads |
215 | # it successfully | 250 | # it successfully |
216 | $(OUTPUT)/test_xdp.o: progs/test_xdp.c | 251 | $(OUTPUT)/test_xdp.o: progs/test_xdp.c |
217 | ($(CLANG) $(CLANG_FLAGS) -O2 -emit-llvm -c $< -o - || \ | 252 | ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -emit-llvm -c $< -o - || \ |
218 | echo "clang failed") | \ | 253 | echo "clang failed") | \ |
219 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ | 254 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ |
220 | ifeq ($(DWARF2BTF),y) | 255 | ifeq ($(DWARF2BTF),y) |
@@ -222,8 +257,8 @@ ifeq ($(DWARF2BTF),y) | |||
222 | endif | 257 | endif |
223 | 258 | ||
224 | $(OUTPUT)/%.o: progs/%.c | 259 | $(OUTPUT)/%.o: progs/%.c |
225 | ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ | 260 | ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -target bpf -emit-llvm \ |
226 | echo "clang failed") | \ | 261 | -c $< -o - || echo "clang failed") | \ |
227 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ | 262 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ |
228 | ifeq ($(DWARF2BTF),y) | 263 | ifeq ($(DWARF2BTF),y) |
229 | $(BTF_PAHOLE) -J $@ | 264 | $(BTF_PAHOLE) -J $@ |
@@ -282,6 +317,6 @@ $(VERIFIER_TESTS_H): $(VERIFIER_TEST_FILES) | $(VERIFIER_TESTS_DIR) | |||
282 | echo '#endif' \ | 317 | echo '#endif' \ |
283 | ) > $(VERIFIER_TESTS_H)) | 318 | ) > $(VERIFIER_TESTS_H)) |
284 | 319 | ||
285 | EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(ALU32_BUILD_DIR) \ | 320 | EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(ALU32_BUILD_DIR) $(BPF_GCC_BUILD_DIR) \ |
286 | $(VERIFIER_TESTS_H) $(PROG_TESTS_H) $(MAP_TESTS_H) \ | 321 | $(VERIFIER_TESTS_H) $(PROG_TESTS_H) $(MAP_TESTS_H) \ |
287 | feature | 322 | feature |
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 6c4930bc6e2e..54a50699bbfd 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
@@ -1,12 +1,6 @@ | |||
1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
2 | #ifndef __BPF_HELPERS_H | 2 | #ifndef __BPF_HELPERS__ |
3 | #define __BPF_HELPERS_H | 3 | #define __BPF_HELPERS__ |
4 | |||
5 | /* helper macro to place programs, maps, license in | ||
6 | * different sections in elf_bpf file. Section names | ||
7 | * are interpreted by elf_bpf loader | ||
8 | */ | ||
9 | #define SEC(NAME) __attribute__((section(NAME), used)) | ||
10 | 4 | ||
11 | #define __uint(name, val) int (*name)[val] | 5 | #define __uint(name, val) int (*name)[val] |
12 | #define __type(name, val) val *name | 6 | #define __type(name, val) val *name |
@@ -19,6 +13,14 @@ | |||
19 | ##__VA_ARGS__); \ | 13 | ##__VA_ARGS__); \ |
20 | }) | 14 | }) |
21 | 15 | ||
16 | #ifdef __clang__ | ||
17 | |||
18 | /* helper macro to place programs, maps, license in | ||
19 | * different sections in elf_bpf file. Section names | ||
20 | * are interpreted by elf_bpf loader | ||
21 | */ | ||
22 | #define SEC(NAME) __attribute__((section(NAME), used)) | ||
23 | |||
22 | /* helper functions called from eBPF programs written in C */ | 24 | /* helper functions called from eBPF programs written in C */ |
23 | static void *(*bpf_map_lookup_elem)(void *map, const void *key) = | 25 | static void *(*bpf_map_lookup_elem)(void *map, const void *key) = |
24 | (void *) BPF_FUNC_map_lookup_elem; | 26 | (void *) BPF_FUNC_map_lookup_elem; |
@@ -256,6 +258,12 @@ struct bpf_map_def { | |||
256 | unsigned int numa_node; | 258 | unsigned int numa_node; |
257 | }; | 259 | }; |
258 | 260 | ||
261 | #else | ||
262 | |||
263 | #include <bpf-helpers.h> | ||
264 | |||
265 | #endif | ||
266 | |||
259 | #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ | 267 | #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ |
260 | struct ____btf_map_##name { \ | 268 | struct ____btf_map_##name { \ |
261 | type_key key; \ | 269 | type_key key; \ |
diff --git a/tools/testing/selftests/bpf/progs/test_tc_edt.c b/tools/testing/selftests/bpf/progs/test_tc_edt.c index 3af64c470d64..0961415ba477 100644 --- a/tools/testing/selftests/bpf/progs/test_tc_edt.c +++ b/tools/testing/selftests/bpf/progs/test_tc_edt.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <stdint.h> | 2 | #include <stdint.h> |
3 | #include <linux/bpf.h> | 3 | #include <linux/bpf.h> |
4 | #include <linux/if_ether.h> | 4 | #include <linux/if_ether.h> |
5 | #include <linux/stddef.h> | ||
5 | #include <linux/in.h> | 6 | #include <linux/in.h> |
6 | #include <linux/ip.h> | 7 | #include <linux/ip.h> |
7 | #include <linux/pkt_cls.h> | 8 | #include <linux/pkt_cls.h> |