Calibrate the CPU ramp per host and fix the deadband leak

Two problems found by A/B against Dell's own profile on an R720xd, 8
minute windows at matched CPU temperature:

The CPU ramp started at a fixed 45c, calibrated on a chassis idling at
48c. On one idling at 58c that sat 40% up the ramp doing nothing useful
and ran 6878 RPM against stock's 6240. The ramp is now derived from the
CPU sensor's own upper-non-critical threshold, and the fan floor is
per-host since PWM->RPM is chassis specific.

The 5 minute re-assert re-pushed the current request rather than the
held value, so the deadband leaked a few percent every interval and the
setpoint drifted 32 -> 36 -> 31. next_fan_speed now separates "has it
moved enough to adopt" from "is it time to re-push".

Also documents that running above stock is correct on hosts whose drives
need it: removing the drives' vote on iz-pve0 hit stock RPM exactly and
took two rear-bay SSDs from 54c to 61c in minutes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Zeb Hering
2026-08-28 21:12:54 -07:00
parent 56ae7542a2
commit 1be394a0ac
3 changed files with 113 additions and 43 deletions

View File

@@ -90,6 +90,41 @@ hour, at which point the alarm is the outage.
`smartctl -H` across two dozen drives runs hourly, not per loop. Absolute and trend
checks stay on the fast loop.
## Calibrating a host
**The defaults are not portable and the fans will be wrong on an uncalibrated host.**
Airflow, bay layout and the PWM→RPM relationship are all chassis specific. Calibration is
a one-off, takes about five minutes, and is what keeps this from being louder than stock:
1. Hand the fans back to Dell and let them settle, then record what stock actually does:
`ipmitool raw 0x30 0x30 0x01 0x01`, wait a minute, then read
`ipmitool sdr type fan` and `ipmitool sdr type temperature`.
2. Take manual control (`ipmitool raw 0x30 0x30 0x01 0x00`) and sweep PWM to find the
percentage that reproduces that RPM:
`ipmitool raw 0x30 0x30 0x02 0xff 0x1c` (0x1c = 28%), waiting ~25s per step.
3. Set `LOW_FAN_SPEED` to that percentage. This is the floor the host idles at.
4. Set `CPU_RAMP_LOW_OFFSET` so the CPU ramp *starts a few degrees above the host's
normal idle*, so idle sits on the floor rather than permanently part-way up a ramp.
Measured example — an R720xd (`iz-pve0`) whose CPUs idle at 60c and whose stock profile
holds 6240 RPM. Here 28% PWM == 6240 RPM, so `LOW_FAN_SPEED=28` and
`CPU_RAMP_LOW_OFFSET=15` (ramp starts at 62c). An R730xd (`iz-pve1`) idling at 48c is
fine on the 18/24 defaults. Put the values in the unit as `Environment=` lines.
### Expect to run above stock on some hosts, legitimately
Dell's profile does not look at drive temperature at all — only CPU, inlet and exhaust.
On `iz-pve0` two rear-bay SSDs sit in preheated exhaust air, and this was measured
directly: raising `DISK_RAMP_LOW_OFFSET` so those drives stopped voting dropped the fans
to 28% (exactly stock's 6240 RPM) and both SSDs climbed 54c → 61c within minutes.
Restoring their vote brought them back to 53-55c at 34% / 7080 RPM.
So on that host **~13% more RPM than stock is the price of keeping two SSDs 6-8c cooler**,
and it is the whole reason this script exists. If you would rather have stock noise and
hotter drives, raise `DISK_RAMP_LOW_OFFSET` until the drives stop asking — that is a
preference, not a bug. What is *not* acceptable is being louder than stock for no reason,
which is what an uncalibrated CPU curve does.
## Trend history
Every pass appends to `log/temps.csv`: