diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-11 21:17:55 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-11 21:17:55 -0400 |
| commit | 52b2c7c109ee3018853f0703de80d9bf039f7e6e (patch) | |
| tree | 5244083120e4b358bc31f50c18f238ae465c209a /tools | |
| parent | 2fcabfbbfac8085a4784c97f4aed3461a4b0bed9 (diff) | |
| download | open-iov-52b2c7c109ee3018853f0703de80d9bf039f7e6e.tar.gz open-iov-52b2c7c109ee3018853f0703de80d9bf039f7e6e.zip | |
guest-diag: scanner EOF guard + exclude non-client nvidia fd holders
Two failure modes found when the scanner detects clients by device fd:
a transient boot nvidia-smi was picked and its exited pagemap read back
EOF, and scan_window advanced by got=0 forever (busy spin, no stream);
and non-client nvidia fd holders must never be committed to. Break on
got<=0 in scan_window (scan_range already did), skip nvidia-smi/
persistenced/Xorg, and prefer /dev/nvidia-uvm holders.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index 29ef114..04aba73 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -659,6 +659,10 @@ def nvidia_fds(pid): def cdt_pid(): prefixes = tuple(p for p in os.environ.get("CLIENT_PREFIXES", "cdt,va,victory").split(",") if p) + # Processes that hold a /dev/nvidia* fd but are not CUDA clients; the + # scanner must never commit to them (a transient nvidia-smi at boot was + # picked once and its exited pagemap read back EOF forever). + non_clients = ("nvidia-smi", "nvidia-persistenced", "Xorg", "X") best = None uvm = None gpu = None @@ -679,6 +683,8 @@ def cdt_pid(): if any(name.startswith(p) for p in prefixes): best = int(d) continue + if any(name.startswith(p) for p in non_clients): + continue # Arbitrary CUDA binaries (any comm) are clients too: match by # the CUDA device they hold open so streaming never depends on # the binary's name. Prefer a UVM holder (compute client) over a @@ -710,6 +716,11 @@ def scan_window(fd, lo, hi, span, out): os.lseek(fd, (va // 4096) * 8, 0) data = os.read(fd, n * 8) got = len(data) // 8 + # EOF: the process's address space (or the pagemap of an exited + # pid) does not reach this VA. Without this the loop reads the + # same offset forever (got == 0 -> va never advances). + if got <= 0: + break for i in range(got): e = int.from_bytes(data[i * 8:i * 8 + 8], 'little') if not ((e >> 63) & 1): |
