diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-31 08:14:08 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-31 08:14:08 -0400 |
| commit | 520ad3e2f99b4e15c8778874e1b4b188c6d16b77 (patch) | |
| tree | 36167c2e02ef74dbdffc69f66d08d908ec42324d /tools/guest-diag/pin_gr_stream.py | |
| parent | f8f0a86a07949f913e546de4459c779a9ccbc3f3 (diff) | |
| download | open-iov-520ad3e2f99b4e15c8778874e1b4b188c6d16b77.tar.gz open-iov-520ad3e2f99b4e15c8778874e1b4b188c6d16b77.zip | |
vgsp+diag: anchored demand record (sema_setup_demand prints VA/off/len), ipin-table eviction (32768 slots silently dropped demand pins; nodrop + alt stash), MME prelude 512->1024 words + SIGS 512; guest_pin_stream resolve_va_strict (host svc_stream_parse port + client-mem /proc/pid/mem+pagemap), pin_gr_stream chunked script push (MAX_ARG_STRLEN) - setup-push read NOW SUCCEEDS (plausible=1 ipin=1 unreadable=0, pa=0x2387b9000), SA table captured, MME-PRELUDE gen=3 words=443, GR LAUNCH words=934, retire 0/903 pages (no writes); new wall: NO 0x114 instruction-RAM upload in any parseable window (code=0) - prelude immature; next: bind setup-hold to the entry carrying the 0x114 uploads - SESSION 153 r1121-r1124
Diffstat (limited to 'tools/guest-diag/pin_gr_stream.py')
| -rw-r--r-- | tools/guest-diag/pin_gr_stream.py | 90 |
1 files changed, 75 insertions, 15 deletions
diff --git a/tools/guest-diag/pin_gr_stream.py b/tools/guest-diag/pin_gr_stream.py index 7a9bb66..35c2ea3 100644 --- a/tools/guest-diag/pin_gr_stream.py +++ b/tools/guest-diag/pin_gr_stream.py @@ -131,11 +131,29 @@ def _demand_send(vas): pass -def _start_cmd(): +def _push_guest_script(): + """Push the scanner into the guest in argv-safe chunks. + + SESSION 153-CONTINUED-64: the one-shot `echo <b64> | base64 -d >` form + put the whole ~135 KB base64 of the (grown) scanner on vgpu_vm.py's + argv, and the host's MAX_ARG_STRLEN (128 KB) rejected the exec before + it ever reached the guest ('OSError: Argument list too long'), so no + scanner started and the boot streamed zero pins. Push 60 KB chunks and + print the guest-side md5 for verification. + """ with open(GUEST_SCRIPT) as f: b64 = subprocess.run(["base64", "-w0"], stdin=f, capture_output=True, text=True, - timeout=10).stdout + timeout=10).stdout.strip() + vexec("rm -f /tmp/gps.b64", 30) + for off in range(0, len(b64), 60000): + vexec("printf %%s '%s' >> /tmp/gps.b64" % b64[off:off + 60000], 30) + return vexec("base64 -d /tmp/gps.b64 > /tmp/guest_pin_stream.py && " + "rm -f /tmp/gps.b64 && md5sum /tmp/guest_pin_stream.py " + "&& echo PUSH_OK", 60) or "" + + +def _start_cmd(): prefixes = os.environ.get("CLIENT_PREFIXES", "cdt,va,victory,Xorg,X,glxgears,gzdoom") vma_every = os.environ.get("STREAM_VMA_EVERY", "1") @@ -151,14 +169,13 @@ def _start_cmd(): # failed silently (r149). return ("P=$(printf '^python3 /tmp/guest_pin_%%s.py' stream); " "sudo pkill -f \"$P\" 2>/dev/null; sleep 1; " - "echo '%s' | base64 -d > /tmp/guest_pin_stream.py; " "sudo rm -f /tmp/guest_pin_stream.pid; " "sudo setsid nohup env CLIENT_PREFIXES='%s' " "STREAM_VMA_EVERY='%s' " "python3 /tmp/guest_pin_stream.py %d %d %s %s %s " ">/tmp/guest_pin_stream.log 2>&1 & sleep 2; " "sudo cat /tmp/guest_pin_stream.pid 2>/dev/null" - % (b64, prefixes, vma_every, 2, PORT, LO, HI, PAMAX)) + % (prefixes, vma_every, 2, PORT, LO, HI, PAMAX)) def install_and_start(): @@ -167,6 +184,14 @@ def install_and_start(): # a boot without the scanner streams no pins and the client then hangs. for attempt in range(5): _heartbeat() + try: + out_push = _push_guest_script() + if "PUSH_OK" not in (out_push or ""): + log("WARN: scanner push attempt %d incomplete: %s" + % (attempt + 1, (out_push or "")[-120:])) + except Exception as e: + log("WARN: scanner push attempt %d failed: %s" + % (attempt + 1, e)) out = vexec(_start_cmd(), 60) if any(ch.isdigit() for ch in out): return True @@ -230,6 +255,13 @@ def _demand_loop(): expiry) as the stalled-VA class. """ track = {} # va -> [first_seen, last_sent] + # SESSION 153-CONTINUED-64: strict demand anchors (entry va -> [first, + # last_sent]) from the anchored debugfs lines. The guest validates the + # exact [entry_va, +len) read window with the host's full stream parse + # before pinning, so the setup-push pin can never land on a page whose + # bytes the host's read will reject. Resent fast (2 s) while the hold + # is up; the loose cadence (20 s) is too slow for the client's churn. + strict_track = {} it = 0 while True: # SESSION 153-CONTINUED-57: the 3 s pass was the losing half of the @@ -296,30 +328,58 @@ def _demand_loop(): "/sys/kernel/debug/vgsp/sema_setup_demand"], capture_output=True, text=True, timeout=10) if rr.returncode == 0: - for m in re.finditer(r"0x[0-9a-f]+", rr.stdout or ""): - sva = int(m.group(0), 16) & ~0xfff - if sva: - track.setdefault(sva, [now, 0.0]) + for line in (rr.stdout or "").splitlines(): + ma = re.match( + r"\s*0x([0-9a-f]+)\s+0x([0-9a-f]+)\s+(\d+)\s*$", + line) + if ma: + ev = int(ma.group(1), 16) + off = int(ma.group(2), 16) + ln = int(ma.group(3)) + if ev and 0 < ln <= 0x40000: + strict_track.setdefault(ev, [now, 0.0, + off, ln]) + continue + for m in re.finditer(r"0x[0-9a-f]+", line): + sva = int(m.group(0), 16) & ~0xfff + if sva: + track.setdefault(sva, [now, 0.0]) except Exception: pass for va in list(track): first, last = track[va] if now - first > 300.0: del track[va] + for ev in list(strict_track): + first, last, off, ln = strict_track[ev] + if now - first > 300.0: + del strict_track[ev] + cmds = [] todo = [va for va, (f, l) in track.items() if now - l > 20.0] - if not todo: + if todo: + todo = todo[:48] + cmds.append(_demand_write_cmd(todo)) + stodo = [ev for ev, (f, l, o, ln) in strict_track.items() + if now - l > 2.0] + if stodo: + stodo = stodo[:16] + cmds.append("; ".join( + "echo S 0x%x 0x%x %d >> /tmp/guest_want_vas.txt" + % (ev, strict_track[ev][2], strict_track[ev][3]) + for ev in stodo)) + if not cmds: continue - # CONT-51: bound one batch's command size (a page-expanded push - # range can add many pages; the remainder goes next cycle). - todo = todo[:48] - cmd = _demand_write_cmd(todo) try: - vexec(cmd, 30) + vexec("; ".join(cmds), 30) except Exception: continue for va in todo: track[va][1] = now - log("demand: sent %d stalled VA(s) to guest" % len(todo)) + for ev in stodo: + strict_track[ev][1] = now + log("demand: sent %d stalled VA(s)%s to guest" % + (len(todo), + " + %d strict anchor(s)" % len(stodo) if stodo else "")) _DEMAND_STARTED = False |
