309 lines
7.4 KiB
Nix
309 lines
7.4 KiB
Nix
{
|
|
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}";
|
|
}
|
|
)
|
|
];
|
|
})
|
|
]
|
|
);
|
|
}
|