2023-11-28 00:47:04 +00:00
|
|
|
project('sched_ext schedulers', 'c',
|
2024-01-25 19:01:23 +00:00
|
|
|
version: '0.1.6',
|
2023-12-03 22:02:44 +00:00
|
|
|
license: 'GPL-2.0')
|
2023-11-28 00:47:04 +00:00
|
|
|
|
2023-12-02 18:09:00 +00:00
|
|
|
if meson.version().version_compare('<1.2')
|
|
|
|
error('meson >= 1.2 required')
|
|
|
|
endif
|
|
|
|
|
2023-12-02 16:41:26 +00:00
|
|
|
fs = import('fs')
|
|
|
|
|
2023-11-28 00:47:04 +00:00
|
|
|
cc = meson.get_compiler('c')
|
|
|
|
|
|
|
|
bpf_clang = find_program(get_option('bpf_clang'))
|
|
|
|
bpftool = find_program(get_option('bpftool'))
|
2023-12-01 21:58:56 +00:00
|
|
|
cargo = find_program(get_option('cargo'))
|
|
|
|
|
2023-12-01 20:20:06 +00:00
|
|
|
get_clang_ver = find_program(join_paths(meson.current_source_dir(),
|
|
|
|
'meson-scripts/get_clang_ver'))
|
2023-11-28 00:47:04 +00:00
|
|
|
bpftool_build_skel = find_program(join_paths(meson.current_source_dir(),
|
|
|
|
'meson-scripts/bpftool_build_skel'))
|
|
|
|
get_sys_incls = find_program(join_paths(meson.current_source_dir(),
|
|
|
|
'meson-scripts/get_sys_incls'))
|
2023-12-08 18:39:06 +00:00
|
|
|
cargo_fetch = find_program(join_paths(meson.current_source_dir(),
|
|
|
|
'meson-scripts/cargo_fetch'))
|
ci: use virtme-ng to test the schedulers
Use virtme-ng to run the schedulers after they're built; virtme-ng
allows to pick an arbitrary sched-ext enabled kernel and run it
virtualizing the entire user-space root filesystem, so we can basically
exceute the recompiled schedulers inside such kernel.
This should allow to catch potential run-time issue in advance (both in
the kernel and the schedulers).
The sched-ext kernel is taken from the Ubuntu ppa (ppa:arighi/sched-ext)
at the moment, since it is the easiest / fastest way to get a
precompiled sched-ext kernel to run inside the Ubuntu 22.04 testing
environment.
The schedulers are tested using the new meson target "test_sched", the
specific actions are defined in meson-scripts/test_sched.
By default each test has a timeout of 30 sec, after the virtme-ng
completes the boot (that should be enough to initialize the scheduler
and run the scheduler for some seconds), while the total lifetime of the
virtme-ng guest is set to 60 sec, after this time the guest will be
killed (this allows to catch potential kernel crashes / hangs).
If a single scheduler fails the test, the entire "test_sched" action
will be interrupted and the overall test result will be considered a
failure.
At the moment scx_layered is excluded from the tests, because it
requires a special configuration (we should probably pre-generate a
default config in the workflow actions and change the scheduler to use
the default config if it's executed without any argument).
Moreover, scx_flatcg is also temporarily excluded from the tests,
because of these known issues:
- https://github.com/sched-ext/scx/issues/49
- https://github.com/sched-ext/sched_ext/pull/101
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
2023-12-24 08:09:25 +00:00
|
|
|
test_sched = find_program(join_paths(meson.current_source_dir(),
|
|
|
|
'meson-scripts/test_sched'))
|
2023-11-28 00:47:04 +00:00
|
|
|
|
2023-12-01 20:20:06 +00:00
|
|
|
bpf_clang_ver = run_command(get_clang_ver, bpf_clang, check: true).stdout().strip()
|
|
|
|
bpf_clang_maj = bpf_clang_ver.split('.')[0].to_int()
|
|
|
|
|
|
|
|
if bpf_clang_maj < 16
|
|
|
|
error('clang < 16 loses high 32 bits of 64 bit enums when compiling BPF (@0@ ver=@1@)'
|
|
|
|
.format(bpf_clang.full_path(), bpf_clang_ver))
|
|
|
|
elif bpf_clang_maj < 17
|
|
|
|
warning('clang >= 17 recommended (@0@ ver=@1@)'
|
|
|
|
.format(bpf_clang.full_path(), bpf_clang_ver))
|
|
|
|
endif
|
|
|
|
|
2023-11-28 00:47:04 +00:00
|
|
|
if get_option('libbpf_a') != ''
|
|
|
|
libbpf_dep = [declare_dependency(
|
|
|
|
link_args: get_option('libbpf_a'),
|
|
|
|
include_directories: get_option('libbpf_h')),
|
|
|
|
cc.find_library('elf'),
|
2023-12-02 16:41:26 +00:00
|
|
|
cc.find_library('z'),
|
|
|
|
cc.find_library('zstd')]
|
2023-11-28 00:47:04 +00:00
|
|
|
else
|
2023-11-28 01:02:33 +00:00
|
|
|
libbpf_dep = dependency('libbpf', version: '>=1.2.2')
|
|
|
|
if libbpf_dep.version().version_compare('<1.3')
|
|
|
|
warning('libbpf <1.3 does not support RESIZE_ARRAY(), expect breakages in schedulers that use them')
|
|
|
|
endif
|
2023-11-28 00:47:04 +00:00
|
|
|
endif
|
|
|
|
|
|
|
|
#
|
2023-12-01 22:15:16 +00:00
|
|
|
# Determine bpf_base_cflags which will be used to compile all .bpf.o files.
|
|
|
|
# Note that "-target bpf" is not included to accommodate
|
2023-11-28 00:47:04 +00:00
|
|
|
# libbpf_cargo::SkeletonBuilder.
|
|
|
|
#
|
|
|
|
# Map https://mesonbuild.com/Reference-tables.html#cpu-families to the
|
|
|
|
# __TARGET_ARCH list in tools/lib/bpf/bpf_tracing.h in the kernel tree.
|
|
|
|
#
|
|
|
|
arch_dict = {
|
|
|
|
'x86': 'x86',
|
|
|
|
'x86_64': 'x86',
|
2023-12-10 08:59:20 +00:00
|
|
|
's390x': 's390',
|
2023-11-28 00:47:04 +00:00
|
|
|
'arm': 'arm',
|
|
|
|
'aarch64': 'arm64',
|
|
|
|
'mips': 'mips',
|
|
|
|
'mips64': 'mips',
|
|
|
|
'ppc': 'powerpc',
|
|
|
|
'ppc64': 'powerpc',
|
|
|
|
'sparc': 'sparc',
|
|
|
|
'sparc64': 'sparc',
|
|
|
|
'riscv32': 'riscv',
|
|
|
|
'riscv64': 'riscv',
|
|
|
|
'arc': 'arc',
|
|
|
|
'loongarch64': 'loongarch'
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu = host_machine.cpu_family()
|
|
|
|
if cpu not in arch_dict
|
|
|
|
error('CPU family "@0@" is not in known arch dict'.format(cpu))
|
|
|
|
endif
|
|
|
|
|
|
|
|
sys_incls = run_command(get_sys_incls, bpf_clang, check: true).stdout().splitlines()
|
2023-12-01 22:15:16 +00:00
|
|
|
bpf_base_cflags = ['-g', '-O2', '-Wall', '-Wno-compare-distinct-pointer-types',
|
|
|
|
'-D__TARGET_ARCH_' + arch_dict[cpu], '-mcpu=v3',
|
|
|
|
'-m@0@-endian'.format(host_machine.endian())] + sys_incls
|
2023-11-28 00:47:04 +00:00
|
|
|
|
2023-12-01 22:15:16 +00:00
|
|
|
message('cpu=@0@ bpf_base_cflags=@1@'.format(cpu, bpf_base_cflags))
|
2023-11-28 00:47:04 +00:00
|
|
|
|
2024-02-03 00:46:24 +00:00
|
|
|
libbpf_c_headers = []
|
|
|
|
|
|
|
|
if get_option('libbpf_a') != ''
|
|
|
|
foreach header: get_option('libbpf_h')
|
|
|
|
libbpf_c_headers += ['-I', header]
|
|
|
|
endforeach
|
|
|
|
endif
|
|
|
|
|
2023-11-28 00:47:04 +00:00
|
|
|
#
|
2023-12-02 18:09:00 +00:00
|
|
|
# Generators to build BPF skel file for C schedulers.
|
2023-11-28 00:47:04 +00:00
|
|
|
#
|
|
|
|
gen_bpf_o = generator(bpf_clang,
|
|
|
|
output: '@BASENAME@.o',
|
2024-02-03 00:46:24 +00:00
|
|
|
arguments: [bpf_base_cflags, '-target', 'bpf', libbpf_c_headers, '@EXTRA_ARGS@',
|
2023-12-01 22:15:16 +00:00
|
|
|
'-c', '@INPUT@', '-o', '@OUTPUT@'])
|
2023-11-28 00:47:04 +00:00
|
|
|
gen_bpf_skel = generator(bpftool_build_skel,
|
|
|
|
output: ['@BASENAME@.skel.h', '@BASENAME@.subskel.h' ],
|
|
|
|
arguments: [bpftool.full_path(), '@INPUT@', '@OUTPUT0@', '@OUTPUT1@'])
|
|
|
|
|
2023-12-01 22:15:16 +00:00
|
|
|
#
|
|
|
|
# For rust sub-projects.
|
|
|
|
#
|
2023-12-02 16:41:26 +00:00
|
|
|
cargo_build_args = ['--quiet']
|
|
|
|
if get_option('buildtype') == 'release'
|
|
|
|
cargo_build_args += '--release'
|
|
|
|
endif
|
|
|
|
|
2023-12-08 18:39:06 +00:00
|
|
|
if get_option('offline')
|
|
|
|
cargo_build_args += '--offline'
|
|
|
|
endif
|
|
|
|
|
2023-12-02 00:49:32 +00:00
|
|
|
cargo_env = environment()
|
|
|
|
cargo_env.set('BPF_CLANG', bpf_clang.full_path())
|
|
|
|
|
|
|
|
foreach flag: bpf_base_cflags
|
|
|
|
cargo_env.append('BPF_BASE_CFLAGS', flag, separator: ' ')
|
|
|
|
endforeach
|
|
|
|
|
|
|
|
if get_option('libbpf_a') != ''
|
|
|
|
foreach header: get_option('libbpf_h')
|
|
|
|
cargo_env.append('BPF_EXTRA_CFLAGS_PRE_INCL', '-I' + header, separator: ' ')
|
|
|
|
endforeach
|
|
|
|
|
2023-12-02 16:41:26 +00:00
|
|
|
cargo_env.append('RUSTFLAGS',
|
|
|
|
'-C link-args=-lelf -C link-args=-lz -C link-args=-lzstd -L '
|
|
|
|
+ fs.parent(get_option('libbpf_a')))
|
|
|
|
|
|
|
|
#
|
|
|
|
# XXX - scx_rusty's original Cargo.toml contained a dependency matching
|
|
|
|
# the following. However, it doesn't seem necessary to enable linking to
|
|
|
|
# libbpf.a. Ask Dan Schatzberg about the role the dependency line plays.
|
|
|
|
#
|
|
|
|
#cargo_build_args += ['--config',
|
|
|
|
# 'dependencies.libbpf-sys.version="1.2"',
|
|
|
|
# '--config',
|
|
|
|
# 'dependencies.libbpf-sys.features=["novendor", "static"]']
|
2023-12-01 22:15:16 +00:00
|
|
|
endif
|
2023-12-01 21:58:56 +00:00
|
|
|
|
2023-12-08 18:39:06 +00:00
|
|
|
if get_option('cargo_home') != ''
|
|
|
|
cargo_env.set('CARGO_HOME', get_option('cargo_home'))
|
|
|
|
endif
|
|
|
|
|
2023-12-09 13:20:44 +00:00
|
|
|
if get_option('enable_rust')
|
|
|
|
meson.add_install_script('meson-scripts/install_rust_user_scheds')
|
|
|
|
endif
|
2023-12-01 23:37:28 +00:00
|
|
|
|
2023-12-08 18:39:06 +00:00
|
|
|
run_target('fetch', command: [cargo_fetch, cargo], env: cargo_env)
|
|
|
|
|
ci: use virtme-ng to test the schedulers
Use virtme-ng to run the schedulers after they're built; virtme-ng
allows to pick an arbitrary sched-ext enabled kernel and run it
virtualizing the entire user-space root filesystem, so we can basically
exceute the recompiled schedulers inside such kernel.
This should allow to catch potential run-time issue in advance (both in
the kernel and the schedulers).
The sched-ext kernel is taken from the Ubuntu ppa (ppa:arighi/sched-ext)
at the moment, since it is the easiest / fastest way to get a
precompiled sched-ext kernel to run inside the Ubuntu 22.04 testing
environment.
The schedulers are tested using the new meson target "test_sched", the
specific actions are defined in meson-scripts/test_sched.
By default each test has a timeout of 30 sec, after the virtme-ng
completes the boot (that should be enough to initialize the scheduler
and run the scheduler for some seconds), while the total lifetime of the
virtme-ng guest is set to 60 sec, after this time the guest will be
killed (this allows to catch potential kernel crashes / hangs).
If a single scheduler fails the test, the entire "test_sched" action
will be interrupted and the overall test result will be considered a
failure.
At the moment scx_layered is excluded from the tests, because it
requires a special configuration (we should probably pre-generate a
default config in the workflow actions and change the scheduler to use
the default config if it's executed without any argument).
Moreover, scx_flatcg is also temporarily excluded from the tests,
because of these known issues:
- https://github.com/sched-ext/scx/issues/49
- https://github.com/sched-ext/sched_ext/pull/101
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
2023-12-24 08:09:25 +00:00
|
|
|
if get_option('kernel') != ''
|
|
|
|
kernel = get_option('kernel')
|
|
|
|
endif
|
|
|
|
|
|
|
|
run_target('test_sched', command: [test_sched, kernel])
|
|
|
|
|
2023-12-09 13:20:44 +00:00
|
|
|
if get_option('enable_rust')
|
|
|
|
subdir('rust')
|
|
|
|
endif
|
2023-11-28 00:47:04 +00:00
|
|
|
subdir('scheds')
|
2024-01-15 22:41:59 +00:00
|
|
|
|
|
|
|
systemd = dependency('systemd', required: get_option('systemd'))
|
|
|
|
|
|
|
|
if systemd.found()
|
|
|
|
subdir('services')
|
|
|
|
endif
|