diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-12 11:51:32 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-12 11:51:32 -0400 |
| commit | 9521339338f096d76fe22c3496ff435a48dffba9 (patch) | |
| tree | 2bf9d7e03431c6049fb1a94b71855f67e2ef7268 | |
| parent | 70a80cc733f94b7bd27ec2e61173e39221c22324 (diff) | |
| download | open-iov-9521339338f096d76fe22c3496ff435a48dffba9.tar.gz open-iov-9521339338f096d76fe22c3496ff435a48dffba9.zip | |
guest-diag: stream the newest client and seed the CE chain from uvch
Two robustness fixes for the sequential client battery. cdt_pid() now
picks the highest-pid CUDA candidate: preferring a name-prefix match
kept the scanner pinned to a previous client that was still tearing
down while the new client had already started pushing, so its first
pushes were unreadable, the release expectation drifted past the real
payloads and the stall followed. The CE push-buffer chain resolver now
also runs for uvch channel kptrs, so the pins do not depend on the uvmt
semaphore events alone.
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index a33a183..35cbfb9 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -755,9 +755,7 @@ def cdt_pid(): # 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 + cands = [] for d in os.listdir('/proc'): if not d.isdigit(): continue @@ -772,28 +770,24 @@ def cdt_pid(): rp = st.rfind(')') if rp >= 0 and st[rp + 2:rp + 3] == 'Z': continue - 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 - # plain /dev/nvidia0 holder (nvidia-smi, persistenced); the last - # match wins, which is the newest client when several overlap. + # the binary's name. The newest candidate (highest pid) is the + # client being streamed: preferring a name-prefix match first + # pinned the scanner to a previous client that was still tearing + # down while the new client had already started pushing (its + # first pushes were unreadable, the expectation drifted, and the + # stall followed). kind = nvidia_fds(d) - if kind == 'uvm': - uvm = int(d) - elif kind == 'gpu': - gpu = int(d) + if kind is not None or any(name.startswith(p) for p in prefixes): + cands.append(int(d)) except OSError: pass - if best is not None: - return best - if uvm is not None: - return uvm - return gpu + if not cands: + return None + return max(cands) def scan_window(fd, lo, hi, span, out): @@ -1131,6 +1125,26 @@ def main(): added += len(got) else: retry_at[ch] = now_r + 1.0 + # A uvch channel kptr is another early seed for the CE + # push-buffer chain (its window contains the pool pointer): + # resolve it here so the pins never depend on the uvmt sem + # events alone. + if ch in resolved_kc_pb or \ + now_r < retry_at.get(("pk", ch), 0): + continue + got = [] + try: + _found = resolve_pb_chain(kc, ch, got) + except Exception: + _found = False + got = [] + if _found: + resolved_kc_pb.add(ch) + if got: + lines.extend(got) + added += len(got) + else: + retry_at[("pk", ch)] = now_r + 2.0 if added: try: with open('/tmp/guest_pin_stream.log', 'a') as f: |
