fix(pcie): stop misclassifying same-vendor non-GPU devices as GPUs

matchesGPUVendor (sat_overlay.go) matched any PCIe DeviceClass containing
the substring "Controller" instead of the actual GPU classes, so a
same-vendor non-GPU device (e.g. an NVIDIA-branded NIC/storage controller)
with a degraded PCIe link surfaced as a pcie:gpu:<vendor> alarm on the
Hardware Summary/webui.

isGPUDevice (app_format.go) had the same bug via a different path: an
"any NVIDIA-vendor device is a GPU" fallback that could inflate the
"GPU: N x <model>" audit summary line with non-GPU companion devices
(NVSwitch/NVLink bridges, etc).

Both now defer to collector.IsGPUClass (exported from the previously
unexported isGPUClass), the canonical exact-match classifier already used
by amdgpu.go — removing the duplicated/incorrect class checks instead of
reimplementing them. Also dedup two more locally-duplicated classifiers
within webui (which doesn't import collector by convention): NIC-class
matching (pages.go/page_topo.go) and GPU-class matching in
page_validate.go now share one copy per package instead of being
reimplemented per file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Mikhail Chusavitin
2026-08-17 12:50:50 +03:00
co-authored by Claude Sonnet 5
parent 4ac9863353
commit e3697c0a11
10 changed files with 92 additions and 28 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ func isAMDGPUDevice(dev schema.HardwarePCIeDevice) bool {
if dev.DeviceClass == nil {
return false
}
return dev.VendorID != nil && *dev.VendorID == AMDVendorID && isGPUClass(strings.TrimSpace(*dev.DeviceClass))
return dev.VendorID != nil && *dev.VendorID == AMDVendorID && IsGPUClass(strings.TrimSpace(*dev.DeviceClass))
}
func queryAMDGPUs() (map[string]amdGPUInfo, error) {
+5 -1
View File
@@ -48,7 +48,11 @@ func isNICClass(class string) bool {
}
}
func isGPUClass(class string) bool {
// IsGPUClass reports whether a normalized PCIe device class (see
// mapPCIeDeviceClass) identifies a GPU/accelerator die itself, as opposed to
// a same-vendor companion device (NIC, storage controller, NVLink bridge,
// audio/USB function, ...) that happens to share the GPU's PCI vendor ID.
func IsGPUClass(class string) bool {
switch strings.TrimSpace(class) {
case "VideoController", "DisplayController", "ProcessingAccelerator":
return true
+1 -1
View File
@@ -51,7 +51,7 @@ func shouldProbePCIeSerial(dev schema.HardwarePCIeDevice) bool {
return false
}
class := strings.TrimSpace(*dev.DeviceClass)
return isNICClass(class) || isGPUClass(class)
return isNICClass(class) || IsGPUClass(class)
}
func queryPCIDeviceSerial(bdf string) string {