Skip to content

Commit 2a52ca7

Browse files
committed
sched_ext: Add scx_simple and scx_example_qmap example schedulers
Add two simple example BPF schedulers - simple and qmap. * simple: In terms of scheduling, it behaves identical to not having any operation implemented at all. The two operations it implements are only to improve visibility and exit handling. On certain homogeneous configurations, this actually can perform pretty well. * qmap: A fixed five level priority scheduler to demonstrate queueing PIDs on BPF maps for scheduling. While not very practical, this is useful as a simple example and will be used to demonstrate different features. v7: - Compat helpers stripped out in prepartion of upstreaming as the upstreamed patchset will be the baselinfe. Utility macros that can be used to implement compat features are kept. - Explicitly disable map autoattach on struct_ops to avoid trying to attach twice while maintaining compatbility with older libbpf. v6: - Common header files reorganized and cleaned up. Compat helpers are added to demonstrate how schedulers can maintain backward compatibility with older kernels while making use of newly added features. - simple_select_cpu() added to keep track of the number of local dispatches. This is needed because the default ops.select_cpu() implementation is updated to dispatch directly and won't call ops.enqueue(). - Updated to reflect the sched_ext API changes. Switching all tasks is the default behavior now and scx_qmap supports partial switching when `-p` is specified. - tools/sched_ext/Kconfig dropped. This will be included in the doc instead. v5: - Improve Makefile. Build artifects are now collected into a separate dir which change be changed. Install and help targets are added and clean actually cleans everything. - MEMBER_VPTR() improved to improve access to structs. ARRAY_ELEM_PTR() and RESIZEABLE_ARRAY() are added to support resizable arrays in .bss. - Add scx_common.h which provides common utilities to user code such as SCX_BUG[_ON]() and RESIZE_ARRAY(). - Use SCX_BUG[_ON]() to simplify error handling. v4: - Dropped _example prefix from scheduler names. v3: - Rename scx_example_dummy to scx_example_simple and restructure a bit to ease later additions. Comment updates. - Added declarations for BPF inline iterators. In the future, hopefully, these will be consolidated into a generic BPF header so that they don't need to be replicated here. v2: - Updated with the generic BPF cpumask helpers. Signed-off-by: Tejun Heo <[email protected]> Reviewed-by: David Vernet <[email protected]> Acked-by: Josh Don <[email protected]> Acked-by: Hao Luo <[email protected]> Acked-by: Barret Rhoden <[email protected]>
1 parent f0e1a06 commit 2a52ca7

File tree

14 files changed

+1499
-2
lines changed

14 files changed

+1499
-2
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,12 @@ ifneq ($(wildcard $(resolve_btfids_O)),)
13551355
$(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean
13561356
endif
13571357

1358+
tools-clean-targets := sched_ext
1359+
PHONY += $(tools-clean-targets)
1360+
$(tools-clean-targets):
1361+
$(Q)$(MAKE) -sC tools $@_clean
1362+
tools_clean: $(tools-clean-targets)
1363+
13581364
# Clear a bunch of variables before executing the submake
13591365
ifeq ($(quiet),silent_)
13601366
tools_silent=s
@@ -1527,7 +1533,7 @@ PHONY += $(mrproper-dirs) mrproper
15271533
$(mrproper-dirs):
15281534
$(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
15291535

1530-
mrproper: clean $(mrproper-dirs)
1536+
mrproper: clean $(mrproper-dirs) tools_clean
15311537
$(call cmd,rmfiles)
15321538
@find . $(RCS_FIND_IGNORE) \
15331539
\( -name '*.rmeta' \) \

tools/Makefile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ help:
2828
@echo ' pci - PCI tools'
2929
@echo ' perf - Linux performance measurement and analysis tool'
3030
@echo ' selftests - various kernel selftests'
31+
@echo ' sched_ext - sched_ext example schedulers'
3132
@echo ' bootconfig - boot config tool'
3233
@echo ' spi - spi tools'
3334
@echo ' tmon - thermal monitoring and tuning tool'
@@ -91,6 +92,9 @@ perf: FORCE
9192
$(Q)mkdir -p $(PERF_O) .
9293
$(Q)$(MAKE) --no-print-directory -C perf O=$(PERF_O) subdir=
9394

95+
sched_ext: FORCE
96+
$(call descend,sched_ext)
97+
9498
selftests: FORCE
9599
$(call descend,testing/$@)
96100

@@ -184,6 +188,9 @@ perf_clean:
184188
$(Q)mkdir -p $(PERF_O) .
185189
$(Q)$(MAKE) --no-print-directory -C perf O=$(PERF_O) subdir= clean
186190

191+
sched_ext_clean:
192+
$(call descend,sched_ext,clean)
193+
187194
selftests_clean:
188195
$(call descend,testing/$(@:_clean=),clean)
189196

@@ -213,6 +220,7 @@ clean: acpi_clean counter_clean cpupower_clean hv_clean firewire_clean \
213220
mm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
214221
freefall_clean build_clean libbpf_clean libsubcmd_clean \
215222
gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
216-
intel-speed-select_clean tracing_clean thermal_clean thermometer_clean thermal-engine_clean
223+
intel-speed-select_clean tracing_clean thermal_clean thermometer_clean thermal-engine_clean \
224+
sched_ext_clean
217225

218226
.PHONY: FORCE

tools/sched_ext/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tools/
2+
build/

tools/sched_ext/Makefile

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
# Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
3+
include ../build/Build.include
4+
include ../scripts/Makefile.arch
5+
include ../scripts/Makefile.include
6+
7+
all: all_targets
8+
9+
ifneq ($(LLVM),)
10+
ifneq ($(filter %/,$(LLVM)),)
11+
LLVM_PREFIX := $(LLVM)
12+
else ifneq ($(filter -%,$(LLVM)),)
13+
LLVM_SUFFIX := $(LLVM)
14+
endif
15+
16+
CLANG_TARGET_FLAGS_arm := arm-linux-gnueabi
17+
CLANG_TARGET_FLAGS_arm64 := aarch64-linux-gnu
18+
CLANG_TARGET_FLAGS_hexagon := hexagon-linux-musl
19+
CLANG_TARGET_FLAGS_m68k := m68k-linux-gnu
20+
CLANG_TARGET_FLAGS_mips := mipsel-linux-gnu
21+
CLANG_TARGET_FLAGS_powerpc := powerpc64le-linux-gnu
22+
CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
23+
CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
24+
CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
25+
CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(ARCH))
26+
27+
ifeq ($(CROSS_COMPILE),)
28+
ifeq ($(CLANG_TARGET_FLAGS),)
29+
$(error Specify CROSS_COMPILE or add '--target=' option to lib.mk)
30+
else
31+
CLANG_FLAGS += --target=$(CLANG_TARGET_FLAGS)
32+
endif # CLANG_TARGET_FLAGS
33+
else
34+
CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
35+
endif # CROSS_COMPILE
36+
37+
CC := $(LLVM_PREFIX)clang$(LLVM_SUFFIX) $(CLANG_FLAGS) -fintegrated-as
38+
else
39+
CC := $(CROSS_COMPILE)gcc
40+
endif # LLVM
41+
42+
CURDIR := $(abspath .)
43+
TOOLSDIR := $(abspath ..)
44+
LIBDIR := $(TOOLSDIR)/lib
45+
BPFDIR := $(LIBDIR)/bpf
46+
TOOLSINCDIR := $(TOOLSDIR)/include
47+
BPFTOOLDIR := $(TOOLSDIR)/bpf/bpftool
48+
APIDIR := $(TOOLSINCDIR)/uapi
49+
GENDIR := $(abspath ../../include/generated)
50+
GENHDR := $(GENDIR)/autoconf.h
51+
52+
ifeq ($(O),)
53+
OUTPUT_DIR := $(CURDIR)/build
54+
else
55+
OUTPUT_DIR := $(O)/build
56+
endif # O
57+
OBJ_DIR := $(OUTPUT_DIR)/obj
58+
INCLUDE_DIR := $(OUTPUT_DIR)/include
59+
BPFOBJ_DIR := $(OBJ_DIR)/libbpf
60+
SCXOBJ_DIR := $(OBJ_DIR)/sched_ext
61+
BINDIR := $(OUTPUT_DIR)/bin
62+
BPFOBJ := $(BPFOBJ_DIR)/libbpf.a
63+
ifneq ($(CROSS_COMPILE),)
64+
HOST_BUILD_DIR := $(OBJ_DIR)/host
65+
HOST_OUTPUT_DIR := host-tools
66+
HOST_INCLUDE_DIR := $(HOST_OUTPUT_DIR)/include
67+
else
68+
HOST_BUILD_DIR := $(OBJ_DIR)
69+
HOST_OUTPUT_DIR := $(OUTPUT_DIR)
70+
HOST_INCLUDE_DIR := $(INCLUDE_DIR)
71+
endif
72+
HOST_BPFOBJ := $(HOST_BUILD_DIR)/libbpf/libbpf.a
73+
RESOLVE_BTFIDS := $(HOST_BUILD_DIR)/resolve_btfids/resolve_btfids
74+
DEFAULT_BPFTOOL := $(HOST_OUTPUT_DIR)/sbin/bpftool
75+
76+
VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \
77+
$(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \
78+
../../vmlinux \
79+
/sys/kernel/btf/vmlinux \
80+
/boot/vmlinux-$(shell uname -r)
81+
VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
82+
ifeq ($(VMLINUX_BTF),)
83+
$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
84+
endif
85+
86+
BPFTOOL ?= $(DEFAULT_BPFTOOL)
87+
88+
ifneq ($(wildcard $(GENHDR)),)
89+
GENFLAGS := -DHAVE_GENHDR
90+
endif
91+
92+
CFLAGS += -g -O2 -rdynamic -pthread -Wall -Werror $(GENFLAGS) \
93+
-I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \
94+
-I$(TOOLSINCDIR) -I$(APIDIR) -I$(CURDIR)/include
95+
96+
# Silence some warnings when compiled with clang
97+
ifneq ($(LLVM),)
98+
CFLAGS += -Wno-unused-command-line-argument
99+
endif
100+
101+
LDFLAGS = -lelf -lz -lpthread
102+
103+
IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \
104+
grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__')
105+
106+
# Get Clang's default includes on this system, as opposed to those seen by
107+
# '-target bpf'. This fixes "missing" files on some architectures/distros,
108+
# such as asm/byteorder.h, asm/socket.h, asm/sockios.h, sys/cdefs.h etc.
109+
#
110+
# Use '-idirafter': Don't interfere with include mechanics except where the
111+
# build would have failed anyways.
112+
define get_sys_includes
113+
$(shell $(1) -v -E - </dev/null 2>&1 \
114+
| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') \
115+
$(shell $(1) -dM -E - </dev/null | grep '__riscv_xlen ' | awk '{printf("-D__riscv_xlen=%d -D__BITS_PER_LONG=%d", $$3, $$3)}')
116+
endef
117+
118+
BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH) \
119+
$(if $(IS_LITTLE_ENDIAN),-mlittle-endian,-mbig-endian) \
120+
-I$(CURDIR)/include -I$(CURDIR)/include/bpf-compat \
121+
-I$(INCLUDE_DIR) -I$(APIDIR) \
122+
-I../../include \
123+
$(call get_sys_includes,$(CLANG)) \
124+
-Wall -Wno-compare-distinct-pointer-types \
125+
-O2 -mcpu=v3
126+
127+
# sort removes libbpf duplicates when not cross-building
128+
MAKE_DIRS := $(sort $(OBJ_DIR)/libbpf $(HOST_BUILD_DIR)/libbpf \
129+
$(HOST_BUILD_DIR)/bpftool $(HOST_BUILD_DIR)/resolve_btfids \
130+
$(INCLUDE_DIR) $(SCXOBJ_DIR) $(BINDIR))
131+
132+
$(MAKE_DIRS):
133+
$(call msg,MKDIR,,$@)
134+
$(Q)mkdir -p $@
135+
136+
$(BPFOBJ): $(wildcard $(BPFDIR)/*.[ch] $(BPFDIR)/Makefile) \
137+
$(APIDIR)/linux/bpf.h \
138+
| $(OBJ_DIR)/libbpf
139+
$(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) OUTPUT=$(OBJ_DIR)/libbpf/ \
140+
EXTRA_CFLAGS='-g -O0 -fPIC' \
141+
DESTDIR=$(OUTPUT_DIR) prefix= all install_headers
142+
143+
$(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \
144+
$(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool
145+
$(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \
146+
ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD) \
147+
EXTRA_CFLAGS='-g -O0' \
148+
OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \
149+
LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \
150+
LIBBPF_DESTDIR=$(HOST_OUTPUT_DIR)/ \
151+
prefix= DESTDIR=$(HOST_OUTPUT_DIR)/ install-bin
152+
153+
$(INCLUDE_DIR)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) | $(INCLUDE_DIR)
154+
ifeq ($(VMLINUX_H),)
155+
$(call msg,GEN,,$@)
156+
$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@
157+
else
158+
$(call msg,CP,,$@)
159+
$(Q)cp "$(VMLINUX_H)" $@
160+
endif
161+
162+
$(SCXOBJ_DIR)/%.bpf.o: %.bpf.c $(INCLUDE_DIR)/vmlinux.h include/scx/*.h \
163+
| $(BPFOBJ) $(SCXOBJ_DIR)
164+
$(call msg,CLNG-BPF,,$(notdir $@))
165+
$(Q)$(CLANG) $(BPF_CFLAGS) -target bpf -c $< -o $@
166+
167+
$(INCLUDE_DIR)/%.bpf.skel.h: $(SCXOBJ_DIR)/%.bpf.o $(INCLUDE_DIR)/vmlinux.h $(BPFTOOL)
168+
$(eval sched=$(notdir $@))
169+
$(call msg,GEN-SKEL,,$(sched))
170+
$(Q)$(BPFTOOL) gen object $(<:.o=.linked1.o) $<
171+
$(Q)$(BPFTOOL) gen object $(<:.o=.linked2.o) $(<:.o=.linked1.o)
172+
$(Q)$(BPFTOOL) gen object $(<:.o=.linked3.o) $(<:.o=.linked2.o)
173+
$(Q)diff $(<:.o=.linked2.o) $(<:.o=.linked3.o)
174+
$(Q)$(BPFTOOL) gen skeleton $(<:.o=.linked3.o) name $(subst .bpf.skel.h,,$(sched)) > $@
175+
$(Q)$(BPFTOOL) gen subskeleton $(<:.o=.linked3.o) name $(subst .bpf.skel.h,,$(sched)) > $(@:.skel.h=.subskel.h)
176+
177+
SCX_COMMON_DEPS := include/scx/common.h include/scx/user_exit_info.h | $(BINDIR)
178+
179+
c-sched-targets = scx_simple scx_qmap
180+
181+
$(addprefix $(BINDIR)/,$(c-sched-targets)): \
182+
$(BINDIR)/%: \
183+
$(filter-out %.bpf.c,%.c) \
184+
$(INCLUDE_DIR)/%.bpf.skel.h \
185+
$(SCX_COMMON_DEPS)
186+
$(eval sched=$(notdir $@))
187+
$(CC) $(CFLAGS) -c $(sched).c -o $(SCXOBJ_DIR)/$(sched).o
188+
$(CC) -o $@ $(SCXOBJ_DIR)/$(sched).o $(HOST_BPFOBJ) $(LDFLAGS)
189+
190+
$(c-sched-targets): %: $(BINDIR)/%
191+
192+
install: all
193+
$(Q)mkdir -p $(DESTDIR)/usr/local/bin/
194+
$(Q)cp $(BINDIR)/* $(DESTDIR)/usr/local/bin/
195+
196+
clean:
197+
rm -rf $(OUTPUT_DIR) $(HOST_OUTPUT_DIR)
198+
rm -f *.o *.bpf.o *.bpf.skel.h *.bpf.subskel.h
199+
rm -f $(c-sched-targets)
200+
201+
help:
202+
@echo 'Building targets'
203+
@echo '================'
204+
@echo ''
205+
@echo ' all - Compile all schedulers'
206+
@echo ''
207+
@echo 'Alternatively, you may compile individual schedulers:'
208+
@echo ''
209+
@printf ' %s\n' $(c-sched-targets)
210+
@echo ''
211+
@echo 'For any scheduler build target, you may specify an alternative'
212+
@echo 'build output path with the O= environment variable. For example:'
213+
@echo ''
214+
@echo ' O=/tmp/sched_ext make all'
215+
@echo ''
216+
@echo 'will compile all schedulers, and emit the build artifacts to'
217+
@echo '/tmp/sched_ext/build.'
218+
@echo ''
219+
@echo ''
220+
@echo 'Installing targets'
221+
@echo '=================='
222+
@echo ''
223+
@echo ' install - Compile and install all schedulers to /usr/bin.'
224+
@echo ' You may specify the DESTDIR= environment variable'
225+
@echo ' to indicate a prefix for /usr/bin. For example:'
226+
@echo ''
227+
@echo ' DESTDIR=/tmp/sched_ext make install'
228+
@echo ''
229+
@echo ' will build the schedulers in CWD/build, and'
230+
@echo ' install the schedulers to /tmp/sched_ext/usr/bin.'
231+
@echo ''
232+
@echo ''
233+
@echo 'Cleaning targets'
234+
@echo '================'
235+
@echo ''
236+
@echo ' clean - Remove all generated files'
237+
238+
all_targets: $(c-sched-targets)
239+
240+
.PHONY: all all_targets $(c-sched-targets) clean help
241+
242+
# delete failed targets
243+
.DELETE_ON_ERROR:
244+
245+
# keep intermediate (.bpf.skel.h, .bpf.o, etc) targets
246+
.SECONDARY:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Dummy gnu/stubs.h. clang can end up including /usr/include/gnu/stubs.h when
3+
* compiling BPF files although its content doesn't play any role. The file in
4+
* turn includes stubs-64.h or stubs-32.h depending on whether __x86_64__ is
5+
* defined. When compiling a BPF source, __x86_64__ isn't set and thus
6+
* stubs-32.h is selected. However, the file is not there if the system doesn't
7+
* have 32bit glibc devel package installed leading to a build failure.
8+
*
9+
* The problem is worked around by making this file available in the include
10+
* search paths before the system one when building BPF.
11+
*/

0 commit comments

Comments
 (0)