78 lines
2.5 KiB
Nix
78 lines
2.5 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
service_configs,
|
|
...
|
|
}:
|
|
{
|
|
boot.initrd.availableKernelModules = [
|
|
"xhci_pci"
|
|
"ahci"
|
|
"usb_storage"
|
|
"usbhid"
|
|
"sd_mod"
|
|
];
|
|
boot.initrd.kernelModules = [ "dm-snapshot" ];
|
|
boot.kernelModules = [ "kvm-amd" ];
|
|
boot.extraModulePackages = [ ];
|
|
|
|
swapDevices = [ ];
|
|
|
|
hardware.cpu.amd.updateMicrocode = true;
|
|
hardware.enableRedistributableFirmware = true;
|
|
|
|
# HDD I/O tuning for torrent seeding workload (high-concurrency random reads).
|
|
#
|
|
# mq-deadline sorts requests into elevator sweeps, reducing seek distance.
|
|
# Aggressive deadlines (15s) let the scheduler accumulate more ops before dispatching,
|
|
# maximizing coalescence — latency is irrelevant since torrent peers tolerate 30-60s.
|
|
# fifo_batch=128 keeps sweeps long; writes_starved=16 heavily favors reads.
|
|
# 4 MiB readahead matches libtorrent piece extent affinity for sequential prefetch.
|
|
#
|
|
# This runs as a systemd oneshot rather than udev rules because the NixOS ZFS module
|
|
# hardcodes a udev rule that forces scheduler="none" on all ZFS member partitions'
|
|
# parent disks, overriding any scheduler set via udev on the disk event.
|
|
systemd.services.hdd-io-tuning = {
|
|
description = "HDD I/O scheduler and queue tuning";
|
|
after = [
|
|
"zfs-import.target"
|
|
"systemd-udev-settle.service"
|
|
];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
};
|
|
path = with pkgs; [
|
|
coreutils
|
|
gawk
|
|
zfs
|
|
];
|
|
script = ''
|
|
# Only tune disks in the hdds pool — not all rotational disks.
|
|
# zpool status gives by-id device names; we resolve to /sys/block/<name>.
|
|
zpool status hdds | awk '/^\t/ && $1 ~ /^(ata-|nvme-|scsi-)/ {print $1}' | while read -r id; do
|
|
link="/dev/disk/by-id/$id"
|
|
[ -L "$link" ] || continue
|
|
name=$(basename "$(readlink -f "$link")")
|
|
dev="/sys/block/$name"
|
|
[ -d "$dev" ] || continue
|
|
|
|
echo mq-deadline > "$dev/queue/scheduler"
|
|
echo 4096 > "$dev/queue/read_ahead_kb"
|
|
echo 512 > "$dev/queue/nr_requests"
|
|
|
|
echo 15000 > "$dev/queue/iosched/read_expire"
|
|
echo 15000 > "$dev/queue/iosched/write_expire"
|
|
echo 128 > "$dev/queue/iosched/fifo_batch"
|
|
echo 16 > "$dev/queue/iosched/writes_starved"
|
|
|
|
echo 4096 > "$dev/queue/max_sectors_kb" 2>/dev/null || true
|
|
|
|
echo "Tuned $id -> $name: mq-deadline, 4M readahead, 15s deadlines"
|
|
done
|
|
'';
|
|
};
|
|
}
|