summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/guest_pmap_win.py
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 14:38:44 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 14:38:44 -0400
commitca944b45ba35f3c0dc63fa9f722067af13e97ab4 (patch)
treea4d0f1f3f2d62cc628ec8af2ca014e1f65d85589 /tools/guest-diag/guest_pmap_win.py
parentdd1135ced1b1e5390034239086784a44bd2fca20 (diff)
downloadopen-iov-ca944b45ba35f3c0dc63fa9f722067af13e97ab4.tar.gz
open-iov-ca944b45ba35f3c0dc63fa9f722067af13e97ab4.zip
tools: pin GR push-buffer window from guest pagemap per boot; widen injected-pin table
The GR channel GPFIFO entries point at pushes in the client GPU VA window (observed 0x200400000 + stride, one allocation per channel) and the pump cannot read them: pushes_nomap grows and the tracking-semaphore releases they carry never land. The pushes are sysmem pages mapped into the client process, so /proc/<pid>/pagemap in the guest gives the GPA. New guest helper guest_pmap_win.py batch-reads the pagemap of a VA range (512 entries per pread). New host tool pin_gr_window.py rescans the window on an interval, follows cdt pid changes, and injects VA->PA runs through sema_map_add (same mechanism as the counters and the CE pushbuffer pins). The injected-pin table grows 8k -> 32k slots so the CE pushbuffer (4096) plus the GR window pages fit without drops.
Diffstat (limited to 'tools/guest-diag/guest_pmap_win.py')
-rw-r--r--tools/guest-diag/guest_pmap_win.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/tools/guest-diag/guest_pmap_win.py b/tools/guest-diag/guest_pmap_win.py
new file mode 100644
index 0000000..a9b74a7
--- /dev/null
+++ b/tools/guest-diag/guest_pmap_win.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+# guest_pmap_win.py - dump present pages of a process's VA range through the
+# guest's own pagemap (root in the guest). Batched reads (512 entries per
+# pread) so a 256 MB window takes about a second, not minutes.
+#
+# Usage: sudo python3 guest_pmap_win.py <pid> <lo-hex> <hi-hex> [max-pairs] [pa-max-hex]
+# Output: one "0x<va>,0x<pa>" line per present page (ascending VA), capped at
+# max-pairs. PAs of 0 are skipped; pages above pa-max are skipped unless 0.
+import os
+import sys
+
+pid = int(sys.argv[1])
+lo = int(sys.argv[2], 16) & ~0xFFF
+hi = int(sys.argv[3], 16)
+maxp = int(sys.argv[4]) if len(sys.argv) > 4 else 20000
+pa_max = int(sys.argv[5], 16) if len(sys.argv) > 5 else 0
+
+BATCH = 512
+out = []
+fd = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY)
+try:
+ va = lo
+ while va < hi:
+ n = min(BATCH, (hi - va) // 0x1000)
+ if n <= 0:
+ break
+ os.lseek(fd, (va // 4096) * 8, 0)
+ data = os.read(fd, n * 8)
+ got = len(data) // 8
+ for i in range(got):
+ e = int.from_bytes(data[i * 8:i * 8 + 8], 'little')
+ if not ((e >> 63) & 1):
+ continue
+ pfn = e & ((1 << 55) - 1)
+ pa = pfn << 12
+ if not pa:
+ continue
+ if pa_max and pa >= pa_max:
+ continue
+ out.append('0x%x,0x%x' % (va + i * 0x1000, pa))
+ if len(out) >= maxp:
+ print('\n'.join(out))
+ sys.exit(0)
+ va += got * 0x1000
+finally:
+ os.close(fd)
+print('\n'.join(out))