Move kernel config to its own role.
This commit is contained in:
308
nix/configuration/roles/kernel/default.nix
Normal file
308
nix/configuration/roles/kernel/default.nix
Normal file
@@ -0,0 +1,308 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
preemption_type = with lib.kernel; {
|
||||
full = {
|
||||
PREEMPT_DYNAMIC = yes;
|
||||
PREEMPT = yes;
|
||||
PREEMPT_VOLUNTARY = lib.mkForce no;
|
||||
PREEMPT_LAZY = lib.mkForce no;
|
||||
PREEMPT_NONE = no;
|
||||
};
|
||||
lazy = {
|
||||
PREEMPT_DYNAMIC = yes;
|
||||
PREEMPT = no;
|
||||
PREEMPT_VOLUNTARY = lib.mkForce no;
|
||||
PREEMPT_LAZY = yes;
|
||||
PREEMPT_NONE = no;
|
||||
};
|
||||
voluntary = {
|
||||
PREEMPT_DYNAMIC = no;
|
||||
PREEMPT = no;
|
||||
PREEMPT_VOLUNTARY = yes;
|
||||
PREEMPT_LAZY = lib.mkForce no;
|
||||
PREEMPT_NONE = no;
|
||||
};
|
||||
none = {
|
||||
PREEMPT_DYNAMIC = no;
|
||||
PREEMPT = no;
|
||||
PREEMPT_VOLUNTARY = lib.mkForce no;
|
||||
PREEMPT_LAZY = lib.mkForce no;
|
||||
PREEMPT_NONE = yes;
|
||||
};
|
||||
};
|
||||
lto_type = with lib.kernel; {
|
||||
none = {
|
||||
LTO_NONE = yes;
|
||||
LTO_CLANG_THIN = no;
|
||||
LTO_CLANG_FULL = no;
|
||||
};
|
||||
thin = {
|
||||
LTO_NONE = no;
|
||||
LTO_CLANG_THIN = yes;
|
||||
LTO_CLANG_FULL = no;
|
||||
};
|
||||
full = {
|
||||
LTO_NONE = no;
|
||||
LTO_CLANG_THIN = no;
|
||||
LTO_CLANG_FULL = yes;
|
||||
};
|
||||
};
|
||||
cpu_scheduler = with lib.kernel; {
|
||||
# Burst-Oriented Response Enhancer
|
||||
# For interactive workloads and gaming.
|
||||
bore = {
|
||||
SCHED_BORE = yes;
|
||||
};
|
||||
# Earliest Eligible Virtual Deadline First
|
||||
# For general purpose computing.
|
||||
eevdf = { };
|
||||
# BitMap Queue CPU Scheduler
|
||||
# For throughput-oriented workloads.
|
||||
bmq = {
|
||||
SCHED_ALT = yes;
|
||||
SCHED_BMQ = yes;
|
||||
};
|
||||
};
|
||||
tick_hz =
|
||||
with lib.kernel;
|
||||
{
|
||||
"1000" = {
|
||||
HZ_1000 = yes;
|
||||
HZ = freeform "1000";
|
||||
};
|
||||
}
|
||||
// lib.genAttrs [ "100" "250" "300" "500" "600" "750" ] (hz: {
|
||||
HZ_1000 = no;
|
||||
"HZ_${hz}" = yes;
|
||||
HZ = freeform hz;
|
||||
});
|
||||
performance_governor = with lib.kernel; {
|
||||
default = {
|
||||
CPU_FREQ_DEFAULT_GOV_SCHEDUTIL = yes;
|
||||
};
|
||||
performance = {
|
||||
CPU_FREQ_DEFAULT_GOV_SCHEDUTIL = no;
|
||||
CPU_FREQ_DEFAULT_GOV_PERFORMANCE = yes;
|
||||
};
|
||||
};
|
||||
cpu_type = with lib.kernel; {
|
||||
x86_64-v1 = {
|
||||
GENERIC_CPU = yes;
|
||||
MZEN4 = no;
|
||||
X86_NATIVE_CPU = no;
|
||||
X86_64_VERSION = freeform "1";
|
||||
};
|
||||
x86_64-v2 = {
|
||||
GENERIC_CPU = yes;
|
||||
MZEN4 = no;
|
||||
X86_NATIVE_CPU = no;
|
||||
X86_64_VERSION = freeform "2";
|
||||
};
|
||||
x86_64-v3 = {
|
||||
GENERIC_CPU = yes;
|
||||
MZEN4 = no;
|
||||
X86_NATIVE_CPU = no;
|
||||
X86_64_VERSION = freeform "3";
|
||||
};
|
||||
x86_64-v4 = {
|
||||
GENERIC_CPU = yes;
|
||||
MZEN4 = no;
|
||||
X86_NATIVE_CPU = no;
|
||||
X86_64_VERSION = freeform "4";
|
||||
};
|
||||
zen4 = {
|
||||
GENERIC_CPU = no;
|
||||
MZEN4 = yes;
|
||||
X86_NATIVE_CPU = no;
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
my_cpu_type = lib.mkMerge [
|
||||
(lib.mkIf (!config.me.optimizations.enable) cpu_type.default)
|
||||
(lib.mkIf (
|
||||
config.me.optimizations.enable && config.me.optimizations.arch == "x86-64-v1"
|
||||
) cpu_type.x86_64-v1)
|
||||
(lib.mkIf (
|
||||
config.me.optimizations.enable && config.me.optimizations.arch == "x86-64-v2"
|
||||
) cpu_type.x86_64-v2)
|
||||
(lib.mkIf (
|
||||
config.me.optimizations.enable && config.me.optimizations.arch == "x86-64-v3"
|
||||
) cpu_type.x86_64-v3)
|
||||
(lib.mkIf (
|
||||
config.me.optimizations.enable && config.me.optimizations.arch == "x86-64-v4"
|
||||
) cpu_type.x86_64-v4)
|
||||
(lib.mkIf (
|
||||
config.me.optimizations.enable && config.me.optimizations.arch == "znver4"
|
||||
) cpu_type.zen4)
|
||||
];
|
||||
tick_rate = with lib.kernel; {
|
||||
# Always tick at the hz frequency.
|
||||
periodic = {
|
||||
NO_HZ_IDLE = no;
|
||||
NO_HZ_FULL = no;
|
||||
NO_HZ = no;
|
||||
NO_HZ_COMMON = no;
|
||||
HZ_PERIODIC = yes;
|
||||
};
|
||||
# Idle - Do not disturb the CPU when idle. This can save power but increase latency.
|
||||
idle = {
|
||||
HZ_PERIODIC = no;
|
||||
NO_HZ_FULL = no;
|
||||
NO_HZ_IDLE = yes;
|
||||
NO_HZ = yes;
|
||||
NO_HZ_COMMON = yes;
|
||||
};
|
||||
# Full dyntick system (tickless) - The kernel tries to shut down the tick whenever possible.
|
||||
tickless = {
|
||||
HZ_PERIODIC = no;
|
||||
NO_HZ_IDLE = no;
|
||||
CONTEXT_TRACKING_FORCE = no;
|
||||
NO_HZ_FULL_NODEF = yes;
|
||||
NO_HZ_FULL = yes;
|
||||
NO_HZ = yes;
|
||||
NO_HZ_COMMON = yes;
|
||||
CONTEXT_TRACKING = yes;
|
||||
};
|
||||
};
|
||||
huge_page = with lib.kernel; {
|
||||
always = {
|
||||
TRANSPARENT_HUGEPAGE_MADVISE = no;
|
||||
TRANSPARENT_HUGEPAGE_ALWAYS = yes;
|
||||
};
|
||||
madvise = {
|
||||
TRANSPARENT_HUGEPAGE_ALWAYS = no;
|
||||
TRANSPARENT_HUGEPAGE_MADVISE = yes;
|
||||
};
|
||||
};
|
||||
io_scheduler = with lib.kernel; {
|
||||
adios = {
|
||||
MQ_IOSCHED_ADIOS = yes;
|
||||
};
|
||||
bfq = {
|
||||
IOSCHED_BFQ = mkKernelOverride yes;
|
||||
};
|
||||
};
|
||||
common_config =
|
||||
with lib.kernel;
|
||||
{
|
||||
# Google's BBRv3 TCP congestion Control
|
||||
TCP_CONG_BBR = yes;
|
||||
DEFAULT_BBR = yes;
|
||||
|
||||
# TCP_CONG_CUBIC = module;
|
||||
# DEFAULT_CUBIC = no;
|
||||
# TCP_CONG_BBR = yes;
|
||||
# DEFAULT_BBR = yes;
|
||||
# DEFAULT_TCP_CONG = freeform "bbr";
|
||||
# NET_SCH_FQ_CODEL = module;
|
||||
# NET_SCH_FQ = yes;
|
||||
# CONFIG_DEFAULT_FQ_CODEL = no;
|
||||
# CONFIG_DEFAULT_FQ = yes;
|
||||
|
||||
# Enable the Control Flow Integrity sanitizer in clang
|
||||
ARCH_SUPPORTS_CFI_CLANG = yes;
|
||||
CFI_CLANG = yes;
|
||||
CFI_AUTO_DEFAULT = yes;
|
||||
|
||||
# Use O3 optimizations
|
||||
CC_OPTIMIZE_FOR_PERFORMANCE = no;
|
||||
CC_OPTIMIZE_FOR_PERFORMANCE_O3 = yes;
|
||||
|
||||
# Enable Adaptive Deadline I/O Scheduler
|
||||
MQ_IOSCHED_ADIOS = yes;
|
||||
}
|
||||
// my_cpu_type;
|
||||
flavors = {
|
||||
server = lib.mkMerge [
|
||||
preemption_type.none
|
||||
lto_type.full
|
||||
cpu_scheduler.eevdf
|
||||
tick_hz."300"
|
||||
performance_governor.default
|
||||
tick_rate.tickless
|
||||
huge_page.madvise
|
||||
];
|
||||
interactive =
|
||||
with lib.kernel;
|
||||
lib.mkMerge [
|
||||
{
|
||||
# Enable RCU Lazy - Reduces power consumption when idle or lightly loaded. Useful for battery-powered devices like laptops.
|
||||
RCU_LAZY = yes;
|
||||
}
|
||||
preemption_type.lazy
|
||||
lto_type.full
|
||||
cpu_scheduler.bore
|
||||
tick_hz."300"
|
||||
performance_governor.default
|
||||
tick_rate.tickless
|
||||
huge_page.madvise
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ ];
|
||||
|
||||
options.me = {
|
||||
kernel.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = "Whether we want to install kernel.";
|
||||
};
|
||||
|
||||
kernel.version = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "linux"; # LTS
|
||||
example = "linux_6_18";
|
||||
description = "What version of the kernl should we use.";
|
||||
};
|
||||
|
||||
kernel.flavor = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "interactive";
|
||||
example = "server";
|
||||
description = "What type of kernel should be built.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.me.kernel.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_me;
|
||||
}
|
||||
(lib.mkIf (!config.me.optimizations.enable) {
|
||||
nixpkgs.overlays = [
|
||||
(final: prev: {
|
||||
linux_me = final."${config.me.kernel.version}";
|
||||
})
|
||||
];
|
||||
})
|
||||
(lib.mkIf (config.me.optimizations.enable) {
|
||||
nixpkgs.overlays = [
|
||||
(
|
||||
final: prev:
|
||||
let
|
||||
addConfig =
|
||||
additionalConfig: pkg:
|
||||
pkg.override (oldconfig: {
|
||||
structuredExtraConfig = lib.mkMerge ([ pkg.structuredExtraConfig ] ++ additionalConfig);
|
||||
});
|
||||
in
|
||||
{
|
||||
linux_me = addConfig ([
|
||||
common_config
|
||||
flavors."${config.me.kernel.flavor}"
|
||||
]) final."${config.me.kernel.version}";
|
||||
}
|
||||
)
|
||||
];
|
||||
})
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
config = lib.mkIf config.me.minimal_base.enable {
|
||||
me.doas.enable = true;
|
||||
me.kernel.enable = true;
|
||||
me.network.enable = true;
|
||||
me.nvme.enable = true;
|
||||
me.ssh.enable = true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
@@ -49,71 +48,13 @@
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf (!config.me.optimizations.enable) (
|
||||
lib.mkMerge [
|
||||
{
|
||||
boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_6_18;
|
||||
# boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux;
|
||||
}
|
||||
]
|
||||
))
|
||||
(lib.mkIf config.me.optimizations.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
boot.kernelPackages = pkgs.linuxPackagesFor pkgs.linux_me;
|
||||
|
||||
nixpkgs.hostPlatform = {
|
||||
gcc.arch = config.me.optimizations.arch;
|
||||
gcc.tune = config.me.optimizations.arch;
|
||||
};
|
||||
|
||||
nixpkgs.overlays = [
|
||||
(
|
||||
final: prev:
|
||||
let
|
||||
addConfig =
|
||||
additionalConfig: pkg:
|
||||
pkg.override (oldconfig: {
|
||||
structuredExtraConfig = pkg.structuredExtraConfig // additionalConfig;
|
||||
});
|
||||
in
|
||||
{
|
||||
linux_me = addConfig {
|
||||
# Server | No preemption - Run until the next tick. Highest throughput but can cause stutter.
|
||||
# PREEMPT = lib.mkOverride 60 lib.kernel.no;
|
||||
# Desktop | Preempt kernel threads only at pre-defined places that call cond_resched().
|
||||
PREEMPT_VOLUNTARY = lib.mkOverride 60 lib.kernel.no;
|
||||
# Low-latency desktop | Full preemption - Kernel threads can be preempted unless they hold a spinlock or are in a no-preemption section.
|
||||
PREEMPT = lib.mkOverride 60 lib.kernel.yes;
|
||||
# RT - All kernel code is preemptible except for a few critical sections.
|
||||
# Middle ground | Real-time tasks preempt immediately like FULL, normal tasks run until the next tick.
|
||||
PREEMPT_LAZY = lib.mkOverride 90 lib.kernel.no;
|
||||
|
||||
# Google's BBRv3 TCP congestion Control
|
||||
TCP_CONG_BBR = lib.kernel.yes;
|
||||
DEFAULT_BBR = lib.kernel.yes;
|
||||
|
||||
# Preemptive Full Tickless Kernel at 300Hz
|
||||
HZ = lib.kernel.freeform "300";
|
||||
HZ_300 = lib.kernel.yes;
|
||||
HZ_1000 = lib.kernel.no;
|
||||
} prev.linux_6_18; # or prev.linux
|
||||
}
|
||||
)
|
||||
(final: prev: {
|
||||
inherit (final.unoptimized)
|
||||
assimp
|
||||
binaryen
|
||||
gsl
|
||||
rapidjson
|
||||
ffmpeg-headless
|
||||
ffmpeg
|
||||
pipewire
|
||||
chromaprint
|
||||
gtkmm
|
||||
;
|
||||
})
|
||||
];
|
||||
}
|
||||
]
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user