summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-11 21:17:55 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-11 21:17:55 -0400
commit9996ac4a93458d6d22085721e2cef18ed41c9215 (patch)
treef2de955c2d99db45c535056e7c18cc9208608d81
parentd2c9054b096e63ca3dd4f890514639f7efd82c3f (diff)
downloadopen-iov-9996ac4a93458d6d22085721e2cef18ed41c9215.tar.gz
open-iov-9996ac4a93458d6d22085721e2cef18ed41c9215.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.
-rw-r--r--tools/guest-diag/guest_pin_stream.py11
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):