diff options
Diffstat (limited to 'tools/guest-diag/semfix_watch.py')
| -rw-r--r-- | tools/guest-diag/semfix_watch.py | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/tools/guest-diag/semfix_watch.py b/tools/guest-diag/semfix_watch.py index 1c33de6..fa435ea 100644 --- a/tools/guest-diag/semfix_watch.py +++ b/tools/guest-diag/semfix_watch.py @@ -392,7 +392,14 @@ def resolve_sem_pool(q, sem): def pin_pushbuffer(q, gpu_vas, cpu, gpa, size=0): """Pin the pushbuffer pages (the UVM allocation is 16 x 1 MB chunks = 16 MB = 4096 pages; the page layout is only piecewise contiguous, so - group ascending-contiguous runs into one bulk injection each).""" + group ascending-contiguous runs into one bulk injection each). + + gva2gpa of a kernel vmalloc VA intermittently fails while the sampled + vCPU executes in user mode (page-table isolation hides the kernel half), + so a pass can miss a run of pages. Do not stop at the first hole: scan + the whole range (bailing only when essentially everything misses) and + return the pinned count, so the caller can retry the remainder later. + """ pages = min(max(size >> 12, 1) if size else PUSHBUF_MAX_PAGES, PUSHBUF_MAX_PAGES) pinned = 0 @@ -403,9 +410,9 @@ def pin_pushbuffer(q, gpu_vas, cpu, gpa, size=0): g = q.gva2gpa(cpu + i * 0x1000) if not g: miss += 1 - if miss >= 64: - print("semfix: pushbuf va=0x%x: %d unmapped pages at %d, stop (%d pinned)" - % (gv, miss, i, pinned), flush=True) + if miss >= pages: + print("semfix: pushbuf va=0x%x: no page resolved (%d " + "tried), wrong cpu base" % (gv, pages), flush=True) return pinned i += 1 continue |
