scx: refactor derivation

Remove individual rust sub packages,
as they were not working in the next version (v1.0.6) when built seperately
Rust sub-packages are now built as scx.rustscheds

Signed-off-by: John Titor <50095635+JohnRTitor@users.noreply.github.com>
This commit is contained in:
John Titor 2024-11-22 17:39:21 +05:30
parent b51fd13e16
commit b284c986f1
No known key found for this signature in database
GPG Key ID: 29B0514F4E3C1CC0
18 changed files with 193 additions and 10002 deletions

View File

@ -1,79 +1,37 @@
{
lib,
callPackage,
pkg-config,
rustPlatform,
llvmPackages,
elfutils,
zlib,
fetchFromGitHub,
}:
let
versionInfo = lib.importJSON ./version.json;
scx-common = rec {
versionInfo = lib.importJSON ./version.json;
# Useful function for packaging schedulers, should be used unless the build system is too complex
# passes some default values like src, version (all of which can be overridden)
mkScxScheduler =
packageType:
args@{ schedulerName, ... }:
(if packageType == "rust" then rustPlatform.buildRustPackage else llvmPackages.stdenv.mkDerivation)
(
args
// {
pname = "${schedulerName}";
version = args.version or versionInfo.scx.version;
inherit (versionInfo.scx) version;
src = args.src or fetchFromGitHub {
owner = "sched-ext";
repo = "scx";
rev = "refs/tags/v${versionInfo.scx.version}";
inherit (versionInfo.scx) hash;
};
src = fetchFromGitHub {
owner = "sched-ext";
repo = "scx";
rev = "refs/tags/v${versionInfo.scx.version}";
inherit (versionInfo.scx) hash;
};
nativeBuildInputs = [
pkg-config
llvmPackages.clang
] ++ (args.nativeBuildInputs or [ ]);
buildInputs = [
elfutils
zlib
] ++ (args.buildInputs or [ ]);
env.LIBCLANG_PATH = args.env.LIBCLANG_PATH or "${lib.getLib llvmPackages.libclang}/lib";
# Needs to be disabled in BPF builds
hardeningDisable = [
"zerocallusedregs"
] ++ (args.hardeningDisable or [ ]);
meta = (args.meta or { }) // {
description = args.meta.description or "";
longDescription =
(args.meta.longDescription or "")
+ ''
\n\nSched-ext schedulers are only available on supported kernels
(6.12 and above or any kernel with the scx patchset applied).'';
homepage = args.meta.homepage or "https://github.com/sched-ext/scx";
license = args.meta.license or lib.licenses.gpl2Only;
platforms = args.meta.platforms or lib.platforms.linux;
maintainers = (args.meta.maintainers or [ ]) ++ (with lib.maintainers; [ johnrtitor ]);
};
}
);
meta = {
homepage = "https://github.com/sched-ext/scx";
changelog = "https://github.com/sched-ext/scx/releases/tag/v${versionInfo.scx.version}";
license = lib.licenses.gpl2Only;
platforms = lib.platforms.linux;
maintainers = with lib.maintainers; [ johnrtitor ];
};
};
schedulers = lib.mergeAttrsList [
{ bpfland = import ./scx_bpfland; }
{ lavd = import ./scx_lavd; }
{ layered = import ./scx_layered; }
{ rlfifo = import ./scx_rlfifo; }
{ rustland = import ./scx_rustland; }
{ rusty = import ./scx_rusty; }
{ cscheds = import ./scx_cscheds.nix; }
{ rustscheds = import ./scx_rustscheds.nix; }
{ full = import ./scx_full.nix; }
];
in
(lib.mapAttrs (name: scheduler: callPackage scheduler { inherit mkScxScheduler; }) schedulers)
(lib.mapAttrs (name: scheduler: callPackage scheduler { inherit scx-common; }) schedulers)
// {
inherit mkScxScheduler;
inherit scx-common;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
{
stdenv,
lib,
mkScxScheduler,
}:
mkScxScheduler "rust" {
schedulerName = "scx_bpfland";
cargoRoot = "scheds/rust/scx_bpfland";
cargoLock.lockFile = ./Cargo.lock;
postPatch = ''
rm Cargo.toml Cargo.lock
ln -fs ${./Cargo.lock} scheds/rust/scx_bpfland/Cargo.lock
'';
preBuild = ''
cd scheds/rust/scx_bpfland
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp target/${stdenv.targetPlatform.config}/release/scx_bpfland $out/bin/
runHook postInstall
'';
meta = {
description = "Sched-ext Rust userspace scheduler";
longDescription = ''
Vruntime-based Sched-ext scheduler that prioritizes interactive workloads. This
scheduler is derived from scx_rustland, but it is fully implemented in BPF. It
has a minimal user-space Rust part to process command line options, collect metrics
and log out scheduling statistics. The BPF part makes all the scheduling decisions.
'';
mainProgram = "scx_bpfland";
};
}

View File

@ -1,53 +1,21 @@
{
stdenv,
lib,
mkScxScheduler,
llvmPackages,
fetchFromGitHub,
writeShellScript,
bash,
meson,
ninja,
jq,
pkg-config,
bpftools,
elfutils,
zlib,
zstd,
scx-common,
}:
let
versionInfo = lib.importJSON ./version.json;
# scx needs a specific commit of bpftool and libbpf
# can be found in meson.build of scx src
# grep 'bpftool_commit =' ./meson.build
bpftools_src = fetchFromGitHub {
owner = "libbpf";
repo = "bpftool";
inherit (versionInfo.bpftool) rev hash;
fetchSubmodules = true;
};
# grep 'libbpf_commit = ' ./meson.build
libbpf_src = fetchFromGitHub {
owner = "libbpf";
repo = "libbpf";
inherit (versionInfo.libbpf) rev hash;
fetchSubmodules = true;
};
# scx needs a specific commit of bpftool
# this imitates the fetch_bpftool script in src/meson-scripts
fetchBpftool = writeShellScript "fetch_bpftool" ''
[ "$2" == '${bpftools_src.rev}' ] || exit 1
cd "$1"
cp --no-preserve=mode,owner -r "${bpftools_src}/" ./bpftool
'';
fetchLibbpf = writeShellScript "fetch_libbpf" ''
[ "$2" == '${libbpf_src.rev}' ] || exit 1
cd "$1"
cp --no-preserve=mode,owner -r "${libbpf_src}/" ./libbpf
mkdir -p ./libbpf/src/usr/include
'';
# Fixes a bug with the meson build script where it specifies
# /bin/bash twice in the script
misbehaviorBash = writeShellScript "bash" ''
@ -56,14 +24,45 @@ let
'';
in
mkScxScheduler "c" {
schedulerName = "scx_cscheds";
llvmPackages.stdenv.mkDerivation (finalAttrs: {
pname = "scx_cscheds";
inherit (scx-common) version src;
# scx needs specific commits of bpftool and libbpf
# can be found in meson.build of scx src
# grep 'bpftool_commit =' ./meson.build
bpftools_src = fetchFromGitHub {
owner = "libbpf";
repo = "bpftool";
inherit (scx-common.versionInfo.bpftool) rev hash;
fetchSubmodules = true;
};
# grep 'libbpf_commit = ' ./meson.build
libbpf_src = fetchFromGitHub {
owner = "libbpf";
repo = "libbpf";
inherit (scx-common.versionInfo.libbpf) rev hash;
fetchSubmodules = true;
};
# this imitates the fetch_bpftool and fetch_libbpf script in src/meson-scripts
fetchBpftool = writeShellScript "fetch_bpftool" ''
[ "$2" == '${finalAttrs.bpftools_src.rev}' ] || exit 1
cd "$1"
cp --no-preserve=mode,owner -r "${finalAttrs.bpftools_src}/" ./bpftool
'';
fetchLibbpf = writeShellScript "fetch_libbpf" ''
[ "$2" == '${finalAttrs.libbpf_src.rev}' ] || exit 1
cd "$1"
cp --no-preserve=mode,owner -r "${finalAttrs.libbpf_src}/" ./libbpf
mkdir -p ./libbpf/src/usr/include
'';
postPatch = ''
rm meson-scripts/fetch_bpftool meson-scripts/fetch_libbpf
patchShebangs ./meson-scripts
cp ${fetchBpftool} meson-scripts/fetch_bpftool
cp ${fetchLibbpf} meson-scripts/fetch_libbpf
cp ${finalAttrs.fetchBpftool} meson-scripts/fetch_bpftool
cp ${finalAttrs.fetchLibbpf} meson-scripts/fetch_libbpf
substituteInPlace meson.build \
--replace-fail '[build_bpftool' "['${misbehaviorBash}', build_bpftool"
'';
@ -72,12 +71,13 @@ mkScxScheduler "c" {
meson
ninja
jq
pkg-config
zstd
] ++ bpftools.buildInputs ++ bpftools.nativeBuildInputs;
buildInputs = [
elfutils
zlib
zstd
];
mesonFlags = [
@ -85,8 +85,8 @@ mkScxScheduler "c" {
# systemd unit is implemented in the nixos module
# upstream systemd files are a hassle to patch
"systemd" = false;
"openrc" = false;
# not for nix
"openrc" = false;
"libalpm" = false;
})
(lib.mapAttrsToList lib.mesonBool {
@ -95,28 +95,50 @@ mkScxScheduler "c" {
# rust based schedulers are built seperately
"enable_rust" = false;
})
# Clang to use when compiling .bpf.c
(lib.mesonOption "bpf_clang" (lib.getExe llvmPackages.clang))
];
hardeningDisable = [
"stackprotector"
"zerocallusedregs"
];
# We copy the compiled header files to the dev output
# These are needed for the rust schedulers
preInstall = ''
mkdir -p ${placeholder "dev"}/libbpf
mkdir -p ${placeholder "dev"}/bpftool
mkdir -p ${placeholder "dev"}/libbpf ${placeholder "dev"}/bpftool
cp -r libbpf/* ${placeholder "dev"}/libbpf/
cp -r bpftool/* ${placeholder "dev"}/bpftool/
'';
outputs = [ "bin" "dev" "out" ];
outputs = [
"bin"
"dev"
"out"
];
# Enable this when default kernel in nixpkgs is 6.12+
doCheck = false;
meta = {
description = "Sched-ext C userspace schedulers";
longDescription = ''
This includes C based schedulers such as scx_central, scx_flatcg,
scx_nest, scx_pair, scx_qmap, scx_simple, scx_userland.
::: {.note}
Sched-ext schedulers are only available on kernels version 6.12 or later.
It is recommended to use the latest kernel for the best compatibility.
:::
'';
inherit (scx-common.meta)
homepage
changelog
license
platforms
maintainers
;
};
}
})

View File

@ -1,20 +1,15 @@
{
stdenv,
lib,
stdenv,
scx-common,
scx,
mkScxScheduler,
}:
scx.cscheds.overrideAttrs (oldAttrs: {
pname = "scx_full";
postInstall =
(oldAttrs.postInstall or "")
+ ''
cp ${lib.getExe scx.bpfland} $out/bin/
cp ${lib.getExe scx.lavd} $out/bin/
cp ${lib.getExe scx.layered} $out/bin/
cp ${lib.getExe scx.rlfifo} $out/bin/
cp ${lib.getExe scx.rustland} $out/bin/
cp ${lib.getExe scx.rusty} $out/bin/
cp ${scx.rustscheds}/bin/* ${placeholder "bin"}/bin/
'';
meta = oldAttrs.meta // {
@ -23,6 +18,11 @@ scx.cscheds.overrideAttrs (oldAttrs: {
This includes C based schedulers such as scx_central, scx_flatcg,
scx_pair, scx_qmap, scx_simple, scx_userland and Rust based schedulers
like scx_rustland, scx_bpfland, scx_lavd, scx_layered, scx_rlfifo.
::: {.note}
Sched-ext schedulers are only available on kernels version 6.12 or later.
It is recommended to use the latest kernel for the best compatibility.
:::
'';
};
})

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +0,0 @@
{
stdenv,
lib,
mkScxScheduler,
}:
mkScxScheduler "rust" {
schedulerName = "scx_lavd";
cargoRoot = "scheds/rust/scx_lavd";
cargoLock.lockFile = ./Cargo.lock;
postPatch = ''
rm Cargo.toml Cargo.lock
ln -fs ${./Cargo.lock} scheds/rust/scx_lavd/Cargo.lock
'';
preBuild = ''
cd scheds/rust/scx_lavd
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp target/${stdenv.targetPlatform.config}/release/scx_lavd $out/bin/
runHook postInstall
'';
meta = {
description = "Sched-ext Rust userspace scheduler";
longDescription = ''
BPF scheduler that implements an LAVD (Latency-criticality Aware Virtual Deadline)
scheduling algorithm. typical use case involves highly interactive applications,
such as gaming, which requires high throughput and low tail latencies.
'';
mainProgram = "scx_lavd";
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +0,0 @@
{
stdenv,
lib,
mkScxScheduler,
}:
mkScxScheduler "rust" {
schedulerName = "scx_layered";
cargoRoot = "scheds/rust/scx_layered";
cargoLock.lockFile = ./Cargo.lock;
postPatch = ''
rm Cargo.toml Cargo.lock
ln -fs ${./Cargo.lock} scheds/rust/scx_layered/Cargo.lock
'';
preBuild = ''
cd scheds/rust/scx_layered
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp target/${stdenv.targetPlatform.config}/release/scx_layered $out/bin/
runHook postInstall
'';
meta = {
description = "Sched-ext Rust userspace scheduler";
longDescription = ''
Highly configurable multi-layer BPF/userspace hybrid scheduler.
It is designed to be highly customizable, and can be targeted for specific applications.
'';
mainProgram = "scx_layered";
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +0,0 @@
{
stdenv,
lib,
mkScxScheduler,
}:
mkScxScheduler "rust" {
schedulerName = "scx_rlfifo";
cargoRoot = "scheds/rust/scx_rlfifo";
cargoLock.lockFile = ./Cargo.lock;
postPatch = ''
rm Cargo.toml Cargo.lock
ln -fs ${./Cargo.lock} scheds/rust/scx_rlfifo/Cargo.lock
'';
preBuild = ''
cd scheds/rust/scx_rlfifo
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp target/${stdenv.targetPlatform.config}/release/scx_rlfifo $out/bin/
runHook postInstall
'';
meta = {
description = "Sched-ext Rust userspace scheduler";
longDescription = ''
scx_rlfifo is a simple FIFO scheduler runs in user-space, based on the
scx_rustland_core framework. Not for production use, but useful to test as a
baseline against complex scheduling polices or for a basic FIFO scheduling approach.
'';
mainProgram = "scx_rlfifo";
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
{
stdenv,
lib,
mkScxScheduler,
}:
mkScxScheduler "rust" {
schedulerName = "scx_rustland";
cargoRoot = "scheds/rust/scx_rustland";
cargoLock.lockFile = ./Cargo.lock;
postPatch = ''
rm Cargo.toml Cargo.lock
ln -fs ${./Cargo.lock} scheds/rust/scx_rustland/Cargo.lock
'';
preBuild = ''
cd scheds/rust/scx_rustland
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp target/${stdenv.targetPlatform.config}/release/scx_rustland $out/bin/
runHook postInstall
'';
meta = {
description = "Sched-ext Rust userspace scheduler";
longDescription = ''
Made of a BPF component (scx_rustland_core) that implements the low level sched-ext functionalities
and a user-space counterpart (scheduler), written in Rust, that implements the actual scheduling policy.
It is designed to prioritize interactive workloads over background CPU-intensive workloads. Typical use
case involves low-latency interactive applications, such as gaming, video conferencing and live streaming.
'';
mainProgram = "scx_rustland";
};
}

View File

@ -0,0 +1,80 @@
{
lib,
rustPlatform,
llvmPackages,
pkg-config,
elfutils,
zlib,
zstd,
scx-common,
scx,
}:
rustPlatform.buildRustPackage {
pname = "scx_rustscheds";
inherit (scx-common) version src;
inherit (scx-common.versionInfo.scx) cargoHash;
# Copy compiled headers and libs from scx.cscheds
postPatch = ''
mkdir bpftool libbpf
cp -r ${scx.cscheds.dev}/bpftool/* bpftool/
cp -r ${scx.cscheds.dev}/libbpf/* libbpf/
'';
nativeBuildInputs = [
pkg-config
llvmPackages.clang
];
buildInputs = [
elfutils
zlib
zstd
];
env = {
LIBCLANG_PATH = "${lib.getLib llvmPackages.libclang}/lib";
BPF_CLANG = lib.getExe llvmPackages.clang;
BPF_EXTRA_CFLAGS_PRE_INCL = lib.concatStringsSep " " [
"-I${scx.cscheds.dev}/libbpf/src/usr/include"
"-I${scx.cscheds.dev}/libbpf/include/uapi"
"-I${scx.cscheds.dev}/libbpf/include/linux"
];
RUSTFLAGS = lib.concatStringsSep " " [
"-C relocation-model=pic"
"-C link-args=-lelf"
"-C link-args=-lz"
"-C link-args=-lzstd"
"-L ${scx.cscheds.dev}/libbpf/src"
];
};
hardeningDisable = [
"stackprotector"
"zerocallusedregs"
];
# Enable this when default kernel in nixpkgs is 6.12+
doCheck = false;
meta = {
description = "Sched-ext Rust userspace schedulers";
longDescription = ''
This includes Rust based schedulers such as
scx_rustland, scx_bpfland, scx_lavd, scx_layered, scx_rlfifo.
::: {.note}
Sched-ext schedulers are only available on kernels version 6.12 or later.
It is recommended to use the latest kernel for the best compatibility.
:::
'';
inherit (scx-common.meta)
homepage
changelog
license
platforms
maintainers
;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
{
stdenv,
lib,
mkScxScheduler,
}:
mkScxScheduler "rust" {
schedulerName = "scx_rusty";
cargoRoot = "scheds/rust/scx_rusty";
cargoLock.lockFile = ./Cargo.lock;
postPatch = ''
rm Cargo.toml Cargo.lock
ln -fs ${./Cargo.lock} scheds/rust/scx_rusty/Cargo.lock
'';
preBuild = ''
cd scheds/rust/scx_rusty
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp target/${stdenv.targetPlatform.config}/release/scx_rusty $out/bin/
runHook postInstall
'';
meta = {
description = "Sched-ext Rust userspace scheduler";
longDescription = ''
Multi-domain, BPF/userspace hybrid scheduler. BPF portion of the scheduler does
a simple round robin in each domain, and the userspace portion calculates the load
factor of each domain, and informs BPF of how tasks should be load balanced accordingly.
Rusty is designed to be flexible, accommodating different architectures and workloads.
'';
mainProgram = "scx_rusty";
};
}

View File

@ -1,13 +1,15 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p coreutils moreutils curl jq nix-prefetch-git cargo gnugrep gawk
#! nix-shell -i bash -p coreutils moreutils curl jq nix-prefetch-git cargo gnugrep gawk nix
# shellcheck shell=bash
# You must run it from the root directory of a nixpkgs repo checkout
set -euo pipefail
versionJson="$(realpath "./pkgs/os-specific/linux/scx/version.json")"
nixFolder="$(dirname "$versionJson")"
localVer=$(jq -r .version <$versionJson)
localVer=$(jq -r .scx.version <$versionJson)
latestVer=$(curl -s https://api.github.com/repos/sched-ext/scx/releases/latest | jq -r .tag_name | sed 's/v//g')
if [ "$localVer" == "$latestVer" ]; then
@ -38,13 +40,18 @@ jq \
.libbpf.rev = \$libbpfRev | .libbpf.hash = \$libbpfHash" \
"$versionJson" | sponge $versionJson
rm -f Cargo.toml Cargo.lock
echo "scx: $localVer -> $latestVer"
for scheduler in bpfland lavd layered rlfifo rustland rusty; do
pushd "scheds/rust/scx_$scheduler"
echo "Updating cargoHash. This may take a while..."
popd
cargoHash=$((nix-build --attr scx.rustscheds 2>&1 || true) | awk '/got/{print $2}')
cargo generate-lockfile
cp Cargo.lock "$nixFolder/scx_$scheduler/Cargo.lock"
if [ -z "$cargoHash" ]; then
echo "Failed to get cargoHash, please update it manually"
exit 0
fi
popd
done
jq \
--arg cargoHash "$cargoHash" \
".scx.cargoHash = \$cargoHash" \
"$versionJson" | sponge $versionJson

View File

@ -1,7 +1,8 @@
{
"scx": {
"version": "1.0.5",
"hash": "sha256-nb2bzEanPPWTUhMmGw/8/bwOkdgNmwoZX2lMFq5Av5Q="
"hash": "sha256-nb2bzEanPPWTUhMmGw/8/bwOkdgNmwoZX2lMFq5Av5Q=",
"cargoHash": "sha256-bBDDNP+f9Ss6+IRFk3at+7+pDLMT6kOlTF1nnx6sqSE="
},
"bpftool": {
"rev": "77a72987353fcae8ce330fd87d4c7afb7677a169",