summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/guest_pin_stream.py
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 15:24:31 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 15:24:31 -0400
commitf4803e303e1e4bfde9f241ec3b6226399d01825d (patch)
tree04563109650c839f70956834f78f0cec513b84e8 /tools/guest-diag/guest_pin_stream.py
parent40411a6837620097efe2cf15f322f0526ae45385 (diff)
downloadopen-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.py60
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: