From c3ac4ceb080d64db668e2160ed273dc3e36c816f Mon Sep 17 00:00:00 2001 From: ClementTsang <34804052+ClementTsang@users.noreply.github.com> Date: Fri, 10 Apr 2026 02:05:28 -0400 Subject: [PATCH] Revert "rework the fds collection step to not hit readlink as much" This reverts commit 7d0207a05b9a48573e24208c635e29f9d1e6ad17. --- src/collection/amd.rs | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/collection/amd.rs b/src/collection/amd.rs index f3ae3a9f..6dc09952 100644 --- a/src/collection/amd.rs +++ b/src/collection/amd.rs @@ -3,7 +3,6 @@ mod amd_gpu_marketing; use std::{ fs::{self, read_to_string}, num::NonZeroU64, - os::unix::fs::{FileTypeExt, MetadataExt}, path::{Path, PathBuf}, sync::{LazyLock, Mutex}, time::{Duration, Instant}, @@ -166,35 +165,20 @@ fn diff_usage(pre: u64, cur: u64, interval: &Duration) -> u64 { .unwrap_or(0) as u64 } -/// Stat the DRM device paths once to get their device numbers. -#[inline] -fn get_drm_dev_numbers(drm_paths: &[PathBuf]) -> Vec { - drm_paths - .iter() - .filter_map(|p| fs::metadata(p).ok().map(|m| m.rdev())) - .collect() -} - -fn get_amdgpu_pid_fds(pid: Pid, drm_dev_numbers: &[u64]) -> Option> { +// from amdgpu_top: https://github.com/Umio-Yasuno/amdgpu_top/blob/c961cf6625c4b6d63fda7f03348323048563c584/crates/libamdgpu_top/src/stat/fdinfo/proc_info.rs#L13-L27 +fn get_amdgpu_pid_fds(pid: Pid, device_path: Vec) -> Option> { let Ok(fd_list) = fs::read_dir(format!("/proc/{pid}/fd/")) else { return None; }; let valid_fds: Vec = fd_list .filter_map(|fd_link| { - let fd_link = fd_link.ok()?; - let fd_num: u32 = fd_link.file_name().to_str()?.parse().ok()?; + let dir_entry = fd_link.map(|fd_link| fd_link.path()).ok()?; + let link = fs::read_link(&dir_entry).ok()?; - // We have to use fs::metadata to traverse symlinks. - let metadata = fs::metadata(fd_link.path()).ok()?; - - // Only character devices can be DRM render nodes. so filter here. - if !metadata.file_type().is_char_device() { - return None; - } - - if drm_dev_numbers.contains(&metadata.rdev()) { - Some(fd_num) + // e.g. "/dev/dri/renderD128" or "/dev/dri/card0" + if device_path.iter().any(|path| link.starts_with(path)) { + dir_entry.file_name()?.to_str()?.parse::().ok() } else { None } @@ -246,7 +230,6 @@ fn get_amd_fdinfo(device_path: &Path) -> Option> { let mut fdinfo = IntMap::default(); let drm_paths = get_amdgpu_drm(device_path)?; - let drm_dev_numbers = get_drm_dev_numbers(&drm_paths); let Ok(proc_dir) = fs::read_dir("/proc") else { return None; @@ -275,7 +258,7 @@ fn get_amd_fdinfo(device_path: &Path) -> Option> { for pid in pids { // collect file descriptors that point to our device renderers - let Some(fds) = get_amdgpu_pid_fds(pid, &drm_dev_numbers) else { + let Some(fds) = get_amdgpu_pid_fds(pid, drm_paths.clone()) else { continue; };