xref: /linux/tools/testing/selftests/sched_ext/Makefile (revision 5f60d5f6bbc12e782fac78110b0ee62698f3b576)
1# SPDX-License-Identifier: GPL-2.0
2# Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
3include ../../../build/Build.include
4include ../../../scripts/Makefile.arch
5include ../../../scripts/Makefile.include
6include ../lib.mk
7
8ifneq ($(LLVM),)
9ifneq ($(filter %/,$(LLVM)),)
10LLVM_PREFIX := $(LLVM)
11else ifneq ($(filter -%,$(LLVM)),)
12LLVM_SUFFIX := $(LLVM)
13endif
14
15CC := $(LLVM_PREFIX)clang$(LLVM_SUFFIX) $(CLANG_FLAGS) -fintegrated-as
16else
17CC := gcc
18endif # LLVM
19
20ifneq ($(CROSS_COMPILE),)
21$(error CROSS_COMPILE not supported for scx selftests)
22endif # CROSS_COMPILE
23
24CURDIR := $(abspath .)
25REPOROOT := $(abspath ../../../..)
26TOOLSDIR := $(REPOROOT)/tools
27LIBDIR := $(TOOLSDIR)/lib
28BPFDIR := $(LIBDIR)/bpf
29TOOLSINCDIR := $(TOOLSDIR)/include
30BPFTOOLDIR := $(TOOLSDIR)/bpf/bpftool
31APIDIR := $(TOOLSINCDIR)/uapi
32GENDIR := $(REPOROOT)/include/generated
33GENHDR := $(GENDIR)/autoconf.h
34SCXTOOLSDIR := $(TOOLSDIR)/sched_ext
35SCXTOOLSINCDIR := $(TOOLSDIR)/sched_ext/include
36
37OUTPUT_DIR := $(CURDIR)/build
38OBJ_DIR := $(OUTPUT_DIR)/obj
39INCLUDE_DIR := $(OUTPUT_DIR)/include
40BPFOBJ_DIR := $(OBJ_DIR)/libbpf
41SCXOBJ_DIR := $(OBJ_DIR)/sched_ext
42BPFOBJ := $(BPFOBJ_DIR)/libbpf.a
43LIBBPF_OUTPUT := $(OBJ_DIR)/libbpf/libbpf.a
44DEFAULT_BPFTOOL := $(OUTPUT_DIR)/sbin/bpftool
45HOST_BUILD_DIR := $(OBJ_DIR)
46HOST_OUTPUT_DIR := $(OUTPUT_DIR)
47
48VMLINUX_BTF_PATHS ?= ../../../../vmlinux					\
49		     /sys/kernel/btf/vmlinux					\
50		     /boot/vmlinux-$(shell uname -r)
51VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
52ifeq ($(VMLINUX_BTF),)
53$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
54endif
55
56BPFTOOL ?= $(DEFAULT_BPFTOOL)
57
58ifneq ($(wildcard $(GENHDR)),)
59  GENFLAGS := -DHAVE_GENHDR
60endif
61
62CFLAGS += -g -O2 -rdynamic -pthread -Wall -Werror $(GENFLAGS)			\
63	  -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR)				\
64	  -I$(TOOLSINCDIR) -I$(APIDIR) -I$(CURDIR)/include -I$(SCXTOOLSINCDIR)
65
66# Silence some warnings when compiled with clang
67ifneq ($(LLVM),)
68CFLAGS += -Wno-unused-command-line-argument
69endif
70
71LDFLAGS = -lelf -lz -lpthread -lzstd
72
73IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null |				\
74			grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__')
75
76# Get Clang's default includes on this system, as opposed to those seen by
77# '-target bpf'. This fixes "missing" files on some architectures/distros,
78# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc.
79#
80# Use '-idirafter': Don't interfere with include mechanics except where the
81# build would have failed anyways.
82define get_sys_includes
83$(shell $(1) -v -E - </dev/null 2>&1 \
84	| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \
85$(shell $(1) -dM -E - </dev/null | grep '__riscv_xlen ' | awk '{printf("-D__riscv_xlen=%d -D__BITS_PER_LONG=%d", $$3, $$3)}')
86endef
87
88BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH)					\
89	     $(if $(IS_LITTLE_ENDIAN),-mlittle-endian,-mbig-endian)		\
90	     -I$(CURDIR)/include -I$(CURDIR)/include/bpf-compat			\
91	     -I$(INCLUDE_DIR) -I$(APIDIR) -I$(SCXTOOLSINCDIR)			\
92	     -I$(REPOROOT)/include						\
93	     $(call get_sys_includes,$(CLANG))					\
94	     -Wall -Wno-compare-distinct-pointer-types				\
95	     -Wno-incompatible-function-pointer-types				\
96	     -O2 -mcpu=v3
97
98# sort removes libbpf duplicates when not cross-building
99MAKE_DIRS := $(sort $(OBJ_DIR)/libbpf $(OBJ_DIR)/libbpf				\
100	       $(OBJ_DIR)/bpftool $(OBJ_DIR)/resolve_btfids			\
101	       $(INCLUDE_DIR) $(SCXOBJ_DIR))
102
103$(MAKE_DIRS):
104	$(call msg,MKDIR,,$@)
105	$(Q)mkdir -p $@
106
107$(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile)			\
108	   $(APIDIR)/linux/bpf.h						\
109	   | $(OBJ_DIR)/libbpf
110	$(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) OUTPUT=$(OBJ_DIR)/libbpf/	\
111		    EXTRA_CFLAGS='-g -O0 -fPIC'					\
112		    DESTDIR=$(OUTPUT_DIR) prefix= all install_headers
113
114$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile)	\
115		    $(LIBBPF_OUTPUT) | $(OBJ_DIR)/bpftool
116	$(Q)$(MAKE) $(submake_extras)  -C $(BPFTOOLDIR)				\
117		    ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD)		\
118		    EXTRA_CFLAGS='-g -O0'					\
119		    OUTPUT=$(OBJ_DIR)/bpftool/					\
120		    LIBBPF_OUTPUT=$(OBJ_DIR)/libbpf/				\
121		    LIBBPF_DESTDIR=$(OUTPUT_DIR)/				\
122		    prefix= DESTDIR=$(OUTPUT_DIR)/ install-bin
123
124$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR)
125ifeq ($(VMLINUX_H),)
126	$(call msg,GEN,,$@)
127	$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
128else
129	$(call msg,CP,,$@)
130	$(Q)cp "$(VMLINUX_H)" $@
131endif
132
133$(SCXOBJ_DIR)/%.bpf.o: %.bpf.c $(INCLUDE_DIR)/vmlinux.h	| $(BPFOBJ) $(SCXOBJ_DIR)
134	$(call msg,CLNG-BPF,,$(notdir $@))
135	$(Q)$(CLANG) $(BPF_CFLAGS) -target bpf -c $< -o $@
136
137$(INCLUDE_DIR)/%.bpf.skel.h: $(SCXOBJ_DIR)/%.bpf.o $(INCLUDE_DIR)/vmlinux.h $(BPFTOOL) | $(INCLUDE_DIR)
138	$(eval sched=$(notdir $@))
139	$(call msg,GEN-SKEL,,$(sched))
140	$(Q)$(BPFTOOL) gen object $(<:.o=.linked1.o) $<
141	$(Q)$(BPFTOOL) gen object $(<:.o=.linked2.o) $(<:.o=.linked1.o)
142	$(Q)$(BPFTOOL) gen object $(<:.o=.linked3.o) $(<:.o=.linked2.o)
143	$(Q)diff $(<:.o=.linked2.o) $(<:.o=.linked3.o)
144	$(Q)$(BPFTOOL) gen skeleton $(<:.o=.linked3.o) name $(subst .bpf.skel.h,,$(sched)) > $@
145	$(Q)$(BPFTOOL) gen subskeleton $(<:.o=.linked3.o) name $(subst .bpf.skel.h,,$(sched)) > $(@:.skel.h=.subskel.h)
146
147################
148# C schedulers #
149################
150
151override define CLEAN
152	rm -rf $(OUTPUT_DIR)
153	rm -f *.o *.bpf.o *.bpf.skel.h *.bpf.subskel.h
154	rm -f $(TEST_GEN_PROGS)
155	rm -f runner
156endef
157
158# Every testcase takes all of the BPF progs are dependencies by default. This
159# allows testcases to load any BPF scheduler, which is useful for testcases
160# that don't need their own prog to run their test.
161all_test_bpfprogs := $(foreach prog,$(wildcard *.bpf.c),$(INCLUDE_DIR)/$(patsubst %.c,%.skel.h,$(prog)))
162
163auto-test-targets :=			\
164	create_dsq			\
165	enq_last_no_enq_fails		\
166	enq_select_cpu_fails		\
167	ddsp_bogus_dsq_fail		\
168	ddsp_vtimelocal_fail		\
169	dsp_local_on			\
170	exit				\
171	hotplug				\
172	init_enable_count		\
173	maximal				\
174	maybe_null			\
175	minimal				\
176	prog_run			\
177	reload_loop			\
178	select_cpu_dfl			\
179	select_cpu_dfl_nodispatch	\
180	select_cpu_dispatch		\
181	select_cpu_dispatch_bad_dsq	\
182	select_cpu_dispatch_dbl_dsp	\
183	select_cpu_vtime		\
184	test_example			\
185
186testcase-targets := $(addsuffix .o,$(addprefix $(SCXOBJ_DIR)/,$(auto-test-targets)))
187
188$(SCXOBJ_DIR)/runner.o: runner.c | $(SCXOBJ_DIR)
189	$(CC) $(CFLAGS) -c $< -o $@
190
191# Create all of the test targets object files, whose testcase objects will be
192# registered into the runner in ELF constructors.
193#
194# Note that we must do double expansion here in order to support conditionally
195# compiling BPF object files only if one is present, as the wildcard Make
196# function doesn't support using implicit rules otherwise.
197$(testcase-targets): $(SCXOBJ_DIR)/%.o: %.c $(SCXOBJ_DIR)/runner.o $(all_test_bpfprogs) | $(SCXOBJ_DIR)
198	$(eval test=$(patsubst %.o,%.c,$(notdir $@)))
199	$(CC) $(CFLAGS) -c $< -o $@ $(SCXOBJ_DIR)/runner.o
200
201$(SCXOBJ_DIR)/util.o: util.c | $(SCXOBJ_DIR)
202	$(CC) $(CFLAGS) -c $< -o $@
203
204runner: $(SCXOBJ_DIR)/runner.o $(SCXOBJ_DIR)/util.o $(BPFOBJ) $(testcase-targets)
205	@echo "$(testcase-targets)"
206	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
207
208TEST_GEN_PROGS := runner
209
210all: runner
211
212.PHONY: all clean help
213
214.DEFAULT_GOAL := all
215
216.DELETE_ON_ERROR:
217
218.SECONDARY:
219