summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-02 11:59:31 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-02 11:59:31 -0500
commit32ec1ca305fe60da413cfe7262e2fbb4bc199a1d (patch)
tree5354fda4b0a4425522135f0ebecc5b3b6edefed9
parent33b708626562abb271b16fddaeffa984fc311d58 (diff)
downloadopen-iov-32ec1ca305fe60da413cfe7262e2fbb4bc199a1d.tar.gz
open-iov-32ec1ca305fe60da413cfe7262e2fbb4bc199a1d.zip
guest-diag: strict-anchor pagemap window fallback un-deadlocks the GL setup-push family
A strict demand anchor (the host's exact [entry_va,+len) read window, e.g. the 60 216 B setup push) whose full-window content parse fails on every candidate used to set strict_pending, and the pend_bases rule then skipped every loose demand VA of the same GL family for as long as the anchor was pending - the host demanded the push's pages individually, the guest suppressed them, and the entry stayed unreadable for the whole generation (r1396: entry 8 unreadable=1 on all generations while its sibling entries read fine; generations churn every ~12 s, the content sweeps take longer). Add _pagemap_window_pin(): on a failed strict resolve, pin the anchor window's pages directly from the client's /proc/pid/pagemap (the r586 mechanism already proven for the non-family draws). The anchor VA is the host's own GPFIFO entry VA, so a present client page is by definition its translation; no content gate and no family learn, so no k/(area,adj) risk. Partial presence heals on the ~2 s anchor resend. A 'strict-pagemap:' log line reports present/total pages either way (0 present => kernel-resident, the fallback cannot help). SESSION 153 r1397; scan: r1397 offline brief Change 1.
-rw-r--r--tools/guest-diag/guest_pin_stream.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py
index e98d851..3222a90 100644
--- a/tools/guest-diag/guest_pin_stream.py
+++ b/tools/guest-diag/guest_pin_stream.py
@@ -2201,6 +2201,42 @@ def scan_range(fd, lo, hi, out):
va += got * 0x1000
+def _pagemap_window_pin(pid, ev, off, ln, out):
+ """Direct client-pagemap pin for [ev, ev+ln) (window-wide r586 fallback).
+
+ SESSION 153-r1397: a strict anchor whose full-window content parse fails
+ (both the kernel-vmap candidates and the client-mem scan) used to set
+ strict_pending and thereby stall EVERY loose demand VA of its family via
+ the pend_bases deferral - the 60 216 B setup push's pages were demanded
+ individually by the host but suppressed, so the entry stayed unreadable
+ for the whole generation (r1396: entry 8 unreadable=1 on all gens while
+ its sibling entries read fine). The anchor VA is the host's own GPFIFO
+ entry VA: when the client maps the pushbuffer at the same VA (rw-s
+ /dev/nvidia mappings - the same premise as the r586 single-page pagemap
+ fallback proven for the non-family draws), a present page IS the
+ translation the host needs; no content gate and no family learn (so no
+ k/(area,adj) risk, no r1120 poisoning class). Partial presence is fine:
+ the anchor resend (~2 s) re-tries and the missing pages heal late.
+ """
+ pfd = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY)
+ try:
+ sub = {}
+ vpg = ev & ~0xFFF
+ end = vpg + ((off + ln + 0xFFF) // 0x1000) * 0x1000
+ scan_range(pfd, vpg, end, sub)
+ if not sub:
+ dbg('strict-pagemap: 0x%x no present page (%u pages)'
+ % (vpg, (end - vpg) >> 12))
+ return False
+ for v, p in sorted(sub.items()):
+ out.append('0x%x,0x%x,1\n' % (v, p))
+ dbg('strict-pagemap: 0x%x -> %u/%u pages pinned'
+ % (vpg, len(sub), (end - vpg) >> 12))
+ return True
+ finally:
+ os.close(pfd)
+
+
def scan_vmas(fd, pid, out):
"""Present pages of the client's high-VA nvidia//dev/zero mappings.
@@ -2522,6 +2558,27 @@ def main():
ok = False
if ok:
got = got2
+ if not ok and pid and eln:
+ # SESSION 153-r1397: a failed content parse must
+ # not make the anchor's pages (and, via
+ # pend_bases, every loose demand VA of its
+ # family) unpinnable. Fall back to the direct
+ # client-pagemap window pin - the VA is the
+ # host's own entry VA, so a present page is by
+ # definition its translation (see
+ # _pagemap_window_pin). This un-deadlocks the
+ # family: on success the anchor counts as
+ # resolved and the deferral lifts; on failure
+ # the 'strict-pagemap:' line says the pages are
+ # not client-pagemap-present (kernel-resident).
+ got2 = []
+ try:
+ ok = _pagemap_window_pin(pid, ev, eoff, eln,
+ got2)
+ except Exception:
+ ok = False
+ if ok:
+ got = got2
if ok and got:
lines.extend(got)
for g in got: