summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 18:01:12 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 18:01:12 -0400
commitf863cf8846a17fc53b75b1235dd2c1804e8efd27 (patch)
tree504d281e05355d0cf359b2dd067d8764a36a1335 /tools
parentebf8e34a348a4563f7581b71a0c0f12d20851561 (diff)
downloadopen-iov-f863cf8846a17fc53b75b1235dd2c1804e8efd27.tar.gz
open-iov-f863cf8846a17fc53b75b1235dd2c1804e8efd27.zip
guest-diag: single-read counter sampler (kills phantom 4-of-20 view); vmrestart reaps stale watchers
Diffstat (limited to 'tools')
-rw-r--r--tools/guest-diag/track_waits.sh36
-rwxr-xr-xtools/guest-diag/vmrestart.sh5
2 files changed, 23 insertions, 18 deletions
diff --git a/tools/guest-diag/track_waits.sh b/tools/guest-diag/track_waits.sh
index 1e3cc91..54c4905 100644
--- a/tools/guest-diag/track_waits.sh
+++ b/tools/guest-diag/track_waits.sh
@@ -28,31 +28,31 @@ pid = int(sys.argv[1]); page = int(sys.argv[2], 16)
count = int(sys.argv[3]); stride = int(sys.argv[4], 16); off = int(sys.argv[5], 16)
pm = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY)
mem = os.open('/proc/%d/mem' % pid, os.O_RDONLY)
+# Window dump start; slots live at [off, off+count*stride) inside the page.
+WIN = 0x200
+WIN_BASE = page + 0xe00
+SLOT0 = off - 0xe00
while True:
ts = time.strftime('%T')
- vals = []
- for i in range(count):
- va = page + off + i * stride
- try:
- os.lseek(pm, (va // 4096) * 8, 0)
- e = int.from_bytes(os.read(pm, 8), 'little')
- present = (e >> 63) & 1
- if present:
- v = int.from_bytes(os.pread(mem, 4, va), 'little')
- vals.append('%d:0x%x' % (i, v))
- else:
- vals.append('%d:-' % i)
- except OSError:
- vals.append('%d:ERR' % i)
- print('%s %s' % (ts, ' '.join(vals)), flush=True)
- # Raw hex dump of the counter window: shows the true slot layout and any
- # value a stride-16 sample would misread.
try:
os.lseek(pm, (page // 4096) * 8, 0)
e = int.from_bytes(os.read(pm, 8), 'little')
if (e >> 63) & 1:
- raw = os.pread(mem, 0x200, page + 0xe00)
+ # One read for both views: per-slot values and the raw dump come
+ # from the same buffer, so they can never disagree. (The old
+ # 20-single-word reader plus a later bulk read produced a
+ # phantom "4 of 20 slots" pattern from a torn/remapped read.)
+ raw = os.pread(mem, WIN, WIN_BASE)
+ vals = []
+ for i in range(count):
+ o = SLOT0 + i * stride
+ v = int.from_bytes(raw[o:o + 4], 'little')
+ vals.append('%d:0x%x' % (i, v))
+ print('%s %s' % (ts, ' '.join(vals)), flush=True)
print('%s RAW %s' % (ts, raw.hex()), flush=True)
+ else:
+ print('%s %s' % (ts, ' '.join('%d:-' % i for i in range(count))),
+ flush=True)
except OSError:
pass
time.sleep(0.5)
diff --git a/tools/guest-diag/vmrestart.sh b/tools/guest-diag/vmrestart.sh
index dbe60ec..5d15852 100755
--- a/tools/guest-diag/vmrestart.sh
+++ b/tools/guest-diag/vmrestart.sh
@@ -6,6 +6,11 @@ set -u
cd "$(dirname "$(readlink -f "$0")")/../.."
sudo pkill -f qemu-system-x86_64 2>/dev/null
+# Reap host-side watchers too: a pin_gr_stream/semfix pair left over from the
+# previous boot holds the vsock port and the single QMP socket slot and will
+# silently corrupt the next run (two QMP clients).
+pkill -f "guest-diag/pin_gr_stream.py" 2>/dev/null
+pkill -f "guest-diag/semfix_uvmt.py" 2>/dev/null
sleep 4
sudo rm -f /tmp/qemu-guest-agent.sock /tmp/qemu-qmp.sock