diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-02 11:59:31 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-02 11:59:31 -0500 |
| commit | 32ec1ca305fe60da413cfe7262e2fbb4bc199a1d (patch) | |
| tree | 5354fda4b0a4425522135f0ebecc5b3b6edefed9 | |
| parent | 33b708626562abb271b16fddaeffa984fc311d58 (diff) | |
| download | open-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.py | 57 |
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: |
