From b4a2692d4612ad68b1d9d397b76ca3853dc74e8f Mon Sep 17 00:00:00 2001 From: Meliox Date: Sun, 23 Aug 2026 16:15:01 +0200 Subject: [PATCH] fix(node_info): Intel GPU detection misidentifying AMD GPUs when intel-gpu-tools is installed --- .../node_info/files/Collector/Intel.pm | 27 ++++++++++++++++- src/modules/node_info/node_info.configure.sh | 30 +++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/modules/node_info/files/Collector/Intel.pm b/src/modules/node_info/files/Collector/Intel.pm index 2122ede..55bfb1d 100644 --- a/src/modules/node_info/files/Collector/Intel.pm +++ b/src/modules/node_info/files/Collector/Intel.pm @@ -5,7 +5,7 @@ use warnings; use Exporter 'import'; use PVE::PVEMod::Config qw(%config $process_type $pve_mod_working_dir); -use PVE::PVEMod::Utils qw(debug check_executable setup_collector_signals safe_write_json); +use PVE::PVEMod::Utils qw(debug check_executable setup_collector_signals safe_write_json read_sysfs); use PVE::PVEMod::Store qw(update_intel_gpu_rrd); our @EXPORT_OK = qw( @@ -13,10 +13,30 @@ our @EXPORT_OK = qw( collector_for_intel_device ); +use constant INTEL_VENDOR_ID => '8086'; + # ============================================================================ # Intel GPU — device discovery # ============================================================================ +# Resolve the PCI vendor ID (lowercase, e.g. "8086") from either a +# "vendor=XXXX" descriptor or a "DDDD:BB:DD.F" address looked up via sysfs. +sub _get_pci_vendor_id { + my ($path) = @_; + + if ($path =~ /vendor=([0-9a-fA-F]{4})/) { + return lc($1); + } + + if ($path =~ m{^pci:([0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.\d+)$}) { + my $vendor = read_sysfs("/sys/bus/pci/devices/$1/vendor"); + $vendor =~ s/^0x//i; + return lc($vendor); + } + + return undef; +} + sub get_intel_gpu_devices { my @devices = (); my $fh; @@ -43,6 +63,11 @@ sub get_intel_gpu_devices { chomp; if (/^(card\d+)\s+(.+?)\s+(pci:[^\s]+)/) { my ($card, $name, $path) = ($1, $2, $3); + my $vendor = _get_pci_vendor_id($path); + if (!defined $vendor || $vendor ne INTEL_VENDOR_ID) { + debug(__LINE__, "Skipping non-Intel device: $card ($path) vendor=" . ($vendor // 'unknown')); + next; + } push @devices, { card => $card, name => $name, diff --git a/src/modules/node_info/node_info.configure.sh b/src/modules/node_info/node_info.configure.sh index ae647ab..ba55906 100644 --- a/src/modules/node_info/node_info.configure.sh +++ b/src/modules/node_info/node_info.configure.sh @@ -59,6 +59,24 @@ _check_nvidia_tool() { return 1 } +# Resolve the PCI vendor ID (lowercase, e.g. "8086") from either a +# "vendor=XXXX" descriptor or a "DDDD:BB:DD.F" address looked up via sysfs. +_get_pci_vendor_id() { + local path="$1" vendor="" + if [[ "$path" =~ vendor=([0-9a-fA-F]{4}) ]]; then + vendor="${BASH_REMATCH[1]}" + elif [[ "$path" =~ ^pci:([0-9a-fA-F]{4}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-9]+)$ ]]; then + local vfile="/sys/bus/pci/devices/${BASH_REMATCH[1]}/vendor" + [[ -f "$vfile" ]] && vendor=$(cat "$vfile") + vendor="${vendor#0x}" + fi + echo "${vendor,,}" +} + +_is_intel_pci_device() { + [[ "$(_get_pci_vendor_id "$1")" == "8086" ]] +} + # --- standard API ------------------------------------------------------------ node_info_defaults() { @@ -338,7 +356,15 @@ node_info_configure() { warn "No Intel GPUs in debug file." fi elif _check_or_install_tool intel_gpu_top intel-gpu-tools "Intel GPU tools (intel-gpu-tools)"; then - intelCards=$(intel_gpu_top -L 2>/dev/null | grep -E '^card[0-9]+' || true) + local rawIntelCards + rawIntelCards=$(intel_gpu_top -L 2>/dev/null | grep -E '^card[0-9]+' || true) + # Filter out non-Intel devices (e.g. AMD cards misdetected when intel-gpu-tools is installed on non-Intel hardware) + while IFS= read -r line; do + [[ -z "$line" ]] && continue + if [[ "$line" =~ (pci:[^[:space:]]+) ]] && _is_intel_pci_device "${BASH_REMATCH[1]}"; then + intelCards+="${intelCards:+$'\n'}$line" + fi + done <<< "$rawIntelCards" if [[ -n "$intelCards" ]]; then info "Intel GPU(s) detected:" echo "$intelCards" | while IFS= read -r line; do echo " $line"; done @@ -363,7 +389,7 @@ node_info_configure() { echo "$json" > "$DEBUG_INTEL_FILE" info "Intel GPU device list saved to $DEBUG_INTEL_FILE" else - warn "No Intel GPUs detected by intel_gpu_top." + warn "No Intel GPUs detected by intel_gpu_top (or none had an Intel PCI vendor ID)." fi fi #endregion Intel GPU