mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:46 +01:00
refactor(aquamarine): cap the R9700 power limit from a udev rule
amdgpu registers power1_cap with its hwmon device, so a rule on each card's hwmon add event replaces the oneshot that polled /sys/class/hwmon for 60 s waiting for both cards to probe. Assisted-by: Claude Code (claude-opus-5-5)
This commit is contained in:
1 parent
2036b97f85
commit
ecf242d6ab
4 files changed
+6
-41
No files matched your search
@@ -255,10 +255,9 @@ equivalent-generation consumer cards are "known to work", and never mentions
|
||||
`Fail to open libdrm_amdgpu.so` message only appeared while the card was wedged (see "ROCm
|
||||
userland in nixpkgs"). Expect `Card Series: N/A` until upstream names the R9700.
|
||||
5. `hardware.amdgpu.overdrive` stays off unless undervolting is wanted; if it is turned on, set
|
||||
`ppfeaturemask = "0xfff7ffff"` (nixpkgs#564601). A oneshot unit in `hardware-amd-gpu.nix` caps
|
||||
both cards at 250 W through hwmon `power1_cap` to keep their fans quiet, and exits non-zero when
|
||||
a card does not take the value; the cap needs no overdrive. `amdgpu.gpu_recovery=1` is set,
|
||||
because the driver default is auto/off except SRIOV.
|
||||
`ppfeaturemask = "0xfff7ffff"` (nixpkgs#564601). A udev rule in `hardware-amd-gpu.nix` caps both
|
||||
cards at 250 W through hwmon `power1_cap` to keep their fans quiet; the cap needs no overdrive.
|
||||
`amdgpu.gpu_recovery=1` is set, because the driver default is auto/off except SRIOV.
|
||||
6. **Open:** set `HIP_VISIBLE_DEVICES` (and `ROCR_VISIBLE_DEVICES` where honoured) so the iGPU is
|
||||
never selected; for llama.cpp prefer `--split-mode layer` or an RPC/pipeline split over tensor
|
||||
parallelism, and build with `-DGGML_HIP=ON -DGPU_TARGETS=gfx1201`, no `HSA_OVERRIDE_GFX_VERSION`.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
pkgs,
|
||||
mylib,
|
||||
myvars,
|
||||
...
|
||||
}:
|
||||
@@ -61,40 +60,9 @@
|
||||
# default. amdgpu exposes the cap in microwatts and accepts anything inside [power1_cap_min,
|
||||
# power1_cap_max] — 210-300 W on these cards. The set path (amdgpu_dpm_set_power_limit) has no
|
||||
# overdrive gate, so the ppfeaturemask default stands.
|
||||
systemd.services.amdgpu-power-cap = {
|
||||
description = "Cap the power limit of every amdgpu card at 250 W";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "systemd-modules-load.service" ];
|
||||
path = [ pkgs.coreutils ];
|
||||
serviceConfig = mylib.systemdHardening.privilegedOneshot // {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = pkgs.writeShellScript "amdgpu-power-cap" ''
|
||||
cap=250000000 # microwatts
|
||||
want=2 # both R9700s; this host has no other amdgpu device
|
||||
# The cards probe asynchronously, so retry briefly instead of racing the driver.
|
||||
for _ in $(seq 1 60); do
|
||||
capped=0
|
||||
for hwmon in /sys/class/hwmon/hwmon*; do
|
||||
[ "$(cat "$hwmon/name" 2>/dev/null)" = amdgpu ] || continue
|
||||
# The subshell keeps a rejected write from printing one shell error per retry; the
|
||||
# summary below is the line an operator needs.
|
||||
if (echo "$cap" > "$hwmon/power1_cap") 2>/dev/null &&
|
||||
[ "$(cat "$hwmon/power1_cap" 2>/dev/null)" = "$cap" ]; then
|
||||
capped=$((capped + 1))
|
||||
fi
|
||||
done
|
||||
if [ "$capped" -ge "$want" ]; then
|
||||
echo "capped $capped amdgpu cards at 250 W"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
echo "amdgpu power cap: only $capped of $want cards took the cap" >&2
|
||||
exit 1
|
||||
'';
|
||||
};
|
||||
};
|
||||
services.udev.extraRules = ''
|
||||
ACTION=="add", SUBSYSTEM=="hwmon", ATTR{name}=="amdgpu", ATTR{power1_cap}="250000000"
|
||||
'';
|
||||
|
||||
# GPU panel in btop, and utilization/VRAM in node_exporter for the shared
|
||||
# VictoriaMetrics scrape — the same shape as the Radeon iGPU hosts.
|
||||
|
||||
@@ -37,7 +37,6 @@ in
|
||||
rapl-permissions = privilegedOneshot // {
|
||||
CapabilityBoundingSet = [ "CAP_CHOWN" ];
|
||||
};
|
||||
amdgpu-power-cap = privilegedOneshot;
|
||||
hdd-no-spindown = privilegedOneshot // {
|
||||
CapabilityBoundingSet = [ "CAP_SYS_RAWIO" ];
|
||||
DeviceAllow = [ "block-sd rw" ];
|
||||
|
||||
@@ -39,7 +39,6 @@ units "youko" [
|
||||
// {
|
||||
privilegedOneshot = {
|
||||
rapl-permissions = privilegedUnit "aquamarine" "rapl-permissions";
|
||||
amdgpu-power-cap = privilegedUnit "aquamarine" "amdgpu-power-cap";
|
||||
hdd-no-spindown = privilegedUnit "youko" "hdd-no-spindown";
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user