From d4cc5f989943f01875dea86b834d90538a748112 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 23 Oct 2026 21:32:31 -0400 Subject: tools: transport-proof demand writes + tolerant demand parsing (the pool-pin latency root cause) The r581 boot's guest scanner died mid-boot with ValueError in main(): "invalid literal for int() with base 16: '0x20400f000\\n0x121000000\\n0x12000ab4c'". A guest-agent transport-escaped append merged demand VAs onto one line with literal backslash-n, and the old parser crashed on it. The crash stopped ALL new pins; the host only re-asserted known pairs, so the UVM pool VA 0x121000000 never arrived while 185 other injections flowed - the pool-pin latency that blocked every validation boot. * pin_gr_stream._demand_send/_demand_loop now write one "echo >>" per VA (no newlines, no backslashes in the transported command; immune to transport escaping). * guest_pin_stream's demand parser extracts every 0x token with re and skips malformed ones instead of raising out of main(). --- tools/guest-diag/guest_pin_stream.py | 17 +++++++++++++++-- tools/guest-diag/pin_gr_stream.py | 26 ++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'tools/guest-diag') diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index aa21655..b56f79d 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -1772,8 +1772,21 @@ def main(): st_d = os.stat("/tmp/guest_want_vas.txt") if st_d.st_mtime != _want_state.get("mtime"): with open("/tmp/guest_want_vas.txt") as fw: - wvas = [int(t, 16) for t in fw.read().split() - if t.startswith("0x")] + # r582: tolerate malformed historical lines. The + # r581 boot's scanner died here: a transport-escaped + # append merged VAs into one token containing + # literal backslash-n ('0x20400f000\\n0x121000000\\n + # ...') and int(t, 16) raised ValueError out of + # main(), stopping ALL new pins (the observed + # pool-pin latency). Extract every 0x token instead; + # a bad token is skipped, never fatal. + wvas = [] + for t in re.findall(r"0x[0-9a-fA-F]+", + fw.read()): + try: + wvas.append(int(t, 16)) + except ValueError: + pass _want_state["mtime"] = st_d.st_mtime for wv in wvas[-64:]: if wv in _want_state["done"]: diff --git a/tools/guest-diag/pin_gr_stream.py b/tools/guest-diag/pin_gr_stream.py index 6eb5be7..ff7e299 100644 --- a/tools/guest-diag/pin_gr_stream.py +++ b/tools/guest-diag/pin_gr_stream.py @@ -100,15 +100,33 @@ def _scanner_alive(): return "ALIVE" in (out or "") +def _demand_write_cmd(vas): + """Build a transport-proof append command for the guest demand file. + + r582: the old `printf '%s' ''` form was mangled by + the guest-agent transport under load - the newlines arrived as LITERAL + backslash-n text and merged VAs onto one line, and the guest scanner's + parser then crashed on `int('0x20400f000\\\\n0x121000000...', 16)` + (ValueError in main; r581 boot scanner log). The scanner's death stopped + ALL new pins while the host only re-asserted known pairs - the observed + pool-pin-latency (0x121000000 never arrived while other injections + flowed). One `echo >> file` per VA carries no newlines and no + backslashes at all, so no transport layer can escape them.""" + return "; ".join("echo 0x%x >> /tmp/guest_want_vas.txt" % va + for va in vas) + + def _demand_send(vas): """Append VA hints to the guest scanner's demand file (best-effort). Same channel pin_gr_stream._demand_loop uses for host-dmesg stalls; the stall watchdog uses it to ask the scanner to re-resolve the fixed pre-capture VAs (counter page / UVM pool) by content/pagemap.""" - lines = "".join("0x%x\n" % va for va in vas) + cmd = _demand_write_cmd(vas) + if not cmd: + return try: - vexec("printf '%%s' '%s' >> /tmp/guest_want_vas.txt" % lines, 30) + vexec(cmd, 30) except Exception: pass @@ -222,9 +240,9 @@ def _demand_loop(): todo = [va for va, (f, l) in track.items() if now - l > 20.0] if not todo: continue - lines = "".join("0x%x\n" % va for va in todo) + cmd = _demand_write_cmd(todo) try: - vexec("printf '%%s' '%s' >> /tmp/guest_want_vas.txt" % lines, 30) + vexec(cmd, 30) except Exception: continue for va in todo: -- cgit v1.2.3