diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 15:24:31 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 15:24:31 -0400 |
| commit | f4803e303e1e4bfde9f241ec3b6226399d01825d (patch) | |
| tree | 04563109650c839f70956834f78f0cec513b84e8 /tools/guest-diag/guest_pin_stream.py | |
| parent | 40411a6837620097efe2cf15f322f0526ae45385 (diff) | |
| download | open-iov-f4803e303e1e4bfde9f241ec3b6226399d01825d.tar.gz open-iov-f4803e303e1e4bfde9f241ec3b6226399d01825d.zip | |
guest-diag: stream uvmt sems over vsock (no guest-agent race); dump channel last release VA; larger push log budget
Diffstat (limited to 'tools/guest-diag/guest_pin_stream.py')
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index bb3f99a..1ff0d3f 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -11,7 +11,9 @@ # # Usage: sudo python3 guest_pin_stream.py [host-cid] [port] [lo-hex] [hi-hex] [pa-max-hex] import os +import re import socket +import subprocess import sys import time @@ -24,6 +26,30 @@ INTERVAL = float(os.environ.get("STREAM_INTERVAL", "0.25")) BATCH = 4096 REGION = 0x200000 SPAN = int(os.environ.get("STREAM_SPAN", "0x10000"), 16) +TRACE = ("/sys/kernel/tracing/trace" + if os.path.exists("/sys/kernel/tracing/trace") + else "/sys/kernel/debug/tracing/trace") +SEM_EVERY = int(os.environ.get("STREAM_SEM_EVERY", "4")) + + +def new_sems(seen): + """New tracking-sem kptrs (uvmt lines) in the trace tail. + + Read in the guest so the host does not need a guest-agent round trip for + every semaphore discovery; the trace is only tailed while a client runs. + """ + try: + out = subprocess.run(["tail", "-c", "262144", TRACE], + capture_output=True, timeout=10).stdout + except Exception: + return [] + found = [] + for m in re.finditer(rb"sem=0x([0-9a-fA-F]+)", out): + v = int(m.group(1), 16) + if v not in seen: + seen.add(v) + found.append(v) + return found def cdt_pid(): @@ -82,18 +108,23 @@ def main(): f.write('%d\n' % os.getpid()) sock = None seen = {} + seen_sems = set() last_pid = None last_log = 0.0 + loop = 0 while True: pid = cdt_pid() + loop += 1 if pid is None: last_pid = None seen = {} + seen_sems = set() time.sleep(INTERVAL) continue if pid != last_pid: last_pid = pid seen = {} + seen_sems = set() if sock is not None: try: sock.sendall(("#pid %d\n" % pid).encode()) @@ -109,28 +140,33 @@ def main(): dt = time.time() - t0 new = [(va, pa) for va, pa in cur.items() if seen.get(va) != pa] seen = cur + lines = [] + if loop % SEM_EVERY == 0: + for sem in new_sems(seen_sems): + lines.append('#sem 0x%x\n' % sem) now = time.time() if now - last_log > 1.0: last_log = now try: with open('/tmp/guest_pin_stream.log', 'a') as f: - f.write('%s pid=%s present=%d new=%d scan=%.3fs\n' - % (time.strftime('%T'), pid, len(cur), len(new), dt)) + f.write('%s pid=%s present=%d new=%d sem=%d scan=%.3fs\n' + % (time.strftime('%T'), pid, len(cur), len(new), + len(seen_sems), dt)) except OSError: pass - if not new: + if not new and not lines: time.sleep(INTERVAL) continue - new.sort() - lines = [] - va0, pa0, n = new[0][0], new[0][1], 1 - for va, pa in new[1:]: - if va == va0 + n * 0x1000 and pa == pa0 + n * 0x1000: - n += 1 - continue + if new: + new.sort() + va0, pa0, n = new[0][0], new[0][1], 1 + for va, pa in new[1:]: + if va == va0 + n * 0x1000 and pa == pa0 + n * 0x1000: + n += 1 + continue + lines.append('0x%x,0x%x,%d\n' % (va0, pa0, n)) + va0, pa0, n = va, pa, 1 lines.append('0x%x,0x%x,%d\n' % (va0, pa0, n)) - va0, pa0, n = va, pa, 1 - lines.append('0x%x,0x%x,%d\n' % (va0, pa0, n)) payload = ''.join(lines).encode() if sock is None: try: |
