pub fn decode_gpu_metrics_throttle(buf: &[u8]) -> Option<ThrottleReasons>Expand description
Decode AMD throttle status from a raw gpu_metrics sysfs blob.
Offsets are derived from the in-tree kernel headers
(drivers/gpu/drm/amd/include/kgd_pp_interface.h for the struct layouts and
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h for the SMU_THROTTLER_*_BIT values).
The structs are naturally aligned, little-endian.
The contract is honest absence on any doubt: a buffer too short for the header, a
structure_size that disagrees with the version’s known length (or is shorter than the
fields we read), an unknown (format, content) revision, or an out-of-bounds field all
yield None. Some is returned only off a successfully decoded struct, because under
§5.4 an all-false ThrottleReasons is an observation of quiet — emitting it from a
blob we could not decode would fabricate a fact-grade “not throttling” forever on any
kernel shipping a revision newer than this table. Garbage content is a broken interface,
which is unobservable too — refusing beats guessing. We never wrap, never panic, and
never narrate a byte we are not certain of.
Mapping precedence: prefer indep_throttle_status (ASIC-independent bits) and split it
into thermal / power_cap / hw_slowdown / other. For older revisions that expose only the
legacy ASIC-specific throttle_status, the per-bit meaning varies by ASIC and is not
safe to map; a nonzero value reliably means “some throttler is active”, so it surfaces
as other alone rather than as a fabricated specific cause.
0xFF sentinel: the SMU memsets the whole metrics table to 0xFF before writing the
fields this ASIC’s firmware supports (smu_cmn.h), so an all-ones word — u64::MAX
indep / u32::MAX legacy — is the firmware’s “never wrote this” marker, NOT 64
simultaneous throttlers. A sentinel word is unobservable: decoding falls through
indep → legacy → None as each word in turn proves unwritten. Cyan Skillfish (BC-250
class) is the known shipper: it emits v2_2 without ever writing indep_throttle_status,
and without this guard every sample would narrate thermal+power+hw_slowdown+other,
permanently.
v3_0 is recognised but its per-sample throttle decode is deliberately None — see the
(3, 0) branch below.