fan: multi-fan RPM with sysfs hwmon fallback for Battlemage/xe (Arc P… - #148
fan: multi-fan RPM with sysfs hwmon fallback for Battlemage/xe (Arc P…#148thevisad wants to merge 1 commit into
Conversation
|
Related to #146 |
|
Hi @thevisad thanks for the contributions! No issues with Windows build or runtime for this PR as well as #149 on Windows Server {2022,2025} and w/ Visual Studio {17(2022),18(2026)}. I really need to set up build actions... :). I'll take a proper look today and should be able to grab a multi-tile system for verification there as well. |
On the Arc Pro B70 (Battlemage, xe) Level Zero sysman enumerates no fan handle, so xpu-smi reports fan speed as N/A even though RPM is published on the world-readable PCI hwmon node (fanN_input). Add per-fan RPM reporting with a validated sysfs fallback. - RPM source is chosen by a pure decideFanRpmSource helper: use Level Zero when fan handles are present; fall back to the hwmon node when Level Zero enumerates no fan or denies access to an unprivileged process; propagate any other enumeration failure so genuine errors are not masked. - Genuine per-fan identity: getSpeedRpmById and getAllSpeedsRpm iterate every Level Zero handle by real fan id, and the sysfs fallback enumerates every fanN_input node; the collector keys samples by real fan id. - Zero RPM (stopped fan) is a valid reading; discovery accepts a hwmon node only when a real RPM value parses; null-pointer and index-overflow are handled. - Pure logic lives in an internal xpum::hwmon utility, off the exported class. The HAL getters propagate Level Zero errors; the stats collector treats an unavailable sample as absent, like other optional metrics. - doctest coverage for the selection matrix, parsing, identity and rendering; portable std::filesystem, no POSIX-only headers. The percent path is unchanged. Validated on Arc Pro B70 (xe, kernel 7.0.0-28-generic, Level Zero 1.27.0): xpu-smi stats reports Fan Speed (RPM) tracking the raw hwmon fan1_input. Signed-off-by: thevisad <373694+thevisad@users.noreply.github.com>
|
@savery42 thanks! One small heads-up from a self-check on my end, since it slipped past both the Linux build and your Windows build: I compile-checked the two internal util TUs standalone under MSVC with /WX, and it surfaced a C4273 (inconsistent dll linkage) on this PR — the internal xpum::hwmon fan helpers in hwmon_fan_utils.h were annotated LIBXPUM_API, i.e. exported from the DLL. That's inconsistent with the temperature helpers (which are plain) and with the goal of keeping them off the exported surface. The full DLL build resolves the macro consistently so it stays green, which is why your Windows build was clean, and it's benign on Linux, so it hid on both sides; only a standalone /WX compile flagged it. Fixed: dropped LIBXPUM_API from the five internal decls. meson test is still 11/11, and both util TUs now compile clean under MSVC /std:c++20 /WX (VS 2022). Pushed to the branch, head 4c089ee. #149 (temperature) was already clean — its helpers never carried the macro. Appreciate you grabbing a multi-tile box for verification — thanks for taking the time on these. |
Description
xpu-smi statsreportsFan Speed (RPM): N/Aon the Intel Arc Pro B70 (Battlemage,xedriver) eventhough the fan is spinning and its RPM is published on the PCI device's hwmon node (
fanN_input): LevelZero sysman enumerates no fan handle on this device. This PR adds per-fan RPM reporting with a sysfs-hwmon
fallback for that case, a correct Level Zero error contract, genuine per-fan identity, and validated
discovery, while leaving the existing percent path byte-identical where Level Zero exposes fan handles.
What it does
decideFanRpmSource(enumResult, fanCount):enumeration failure → propagate;
fanCount == 0→ sysfs;fanCount >= 1→ Level Zero. sysfs isnever consulted when a fan handle exists.
getSpeedRpmByIdreads a specific L0 handle (propagates its error; acceptsrpm >= 0);getAllSpeedsRpmiterates all L0 handles keyed by real fan id, and in the zero-handlecase enumerates all
fanN_inputnodes (fan1_input→0,fan2_input→1, …). The stats collectorkeys samples by real fan id — no fan is dropped.
resolveSysfsHwmonsetszes_pci_properties_t.stype(required by the Level Zero API contract), scansall
hwmon*nodes, and accepts a candidate only when a real RPM value parses (not merely that thefile opens), so a malformed node cannot shadow a valid one.
readFanInputFromDirreturnsZE_RESULT_ERROR_INVALID_NULL_POINTERfor a null out-pointer;parseFanInputIndexusesstd::from_charsand rejects overflow.xpum::hwmonutility (hwmon_fan_utils.{h,cpp}), not on the exportedfanclass. The HAL getters propagate Level Zero errors and never substitute a sysfs value for a realdriver failure; the stats collector treats an unavailable RPM sample as absent (like other optional
xpu-smi statsmetrics), so it does not makexpu-smiexit with the Level Zero failure.Testing
decideFanRpmSourcematrix incl. inconsistentfanCount>0 && handles==nullptr→internal error; RPM parse incl.0, malformed, overflow; index parsereadFanInputFromDiragainst a temp hwmon dir incl. null-ptr classification;percent-rendering unchanged vs
" RPM"rendering). Fullmeson test: 11/11 suites.xe, kernel7.0.0-28-generic, Level Zero1.27.0):xpu-smi statsreportsFan Speed (RPM) Fan 0: 1177 RPM, tracking rawfan1_input;Fan Speed (%)staysN/A; discoveryselected the correct hwmon node.
Scope / limitations
fanN_inputin the fallback) buthardware-validated only on the single-fan B70; the multi-fan paths are exercised by unit tests, not on
multi-fan silicon.
zesFanGetStatefailing on a present handle) iscovered by the selection logic but not unit-mocked, because injecting that failure would require
fabricating a device handle; documented in the code.
EAGAINon a back-to-back read, so hwmon resolution isvalidated once and cached rather than re-read every sample.
std::filesystem). Windows was not build-tested. The doctesttest targets require a
doctestpackage in CI.Fixes:
Relates-To:
Type of change
Affected components
hal— Hardware Abstraction Layerial— Interface / Application Layeroal— OS Abstraction Layerxpumd— XPU Manager Daemoncli/smici/ build systemChecklist
Signed-off-by(DCO)Fan Speed (RPM)row /fan.speed_rpmmetric is described here; no new CLI option