summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/guest-diag/guest_pin_stream.py50
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: