summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-12 17:26:11 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-12 17:26:11 -0400
commitade77d9a5f80cb54dc8587f75e066679ca98884e (patch)
tree972cca9b952b7f4250a67a4189322c0a26399748 /tools/guest-diag
parentbb5397afd7afcb97865508ff8c23963ffcd5334f (diff)
downloadopen-iov-ade77d9a5f80cb54dc8587f75e066679ca98884e.tar.gz
open-iov-ade77d9a5f80cb54dc8587f75e066679ca98884e.zip
guest-diag: channel-anchored CE pool resolution for the spinning tracking-sem case
The second-client stall leaves exactly one live uvmt event: a tracking semaphore spinning with val=0 (the other channel/one-shot probes are inlined in this driver build and never fire). The sem is a member of a uvm_channel_t whose records sit in the sem's own window and carry the CE ring GPU VA (0x121010000+) plus back-to-back object handles; the channel's pool pointer is the first field at channel+0 (channel = sem-0x80), and the pool chain already satisfies _chain_mems_at once it is tried. The resolver now expands the candidate set from every ring-VA word's surrounding records and their targets before scoring. Verified live: the r134 spinning sem resolves to the CE push-buffer rm_mem with 413 pin runs, where the bare sem-window scan had produced none.
Diffstat (limited to 'tools/guest-diag')
-rw-r--r--tools/guest-diag/guest_pin_stream.py36
1 files changed, 36 insertions, 0 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py
index 885a87e..49974c9 100644
--- a/tools/guest-diag/guest_pin_stream.py
+++ b/tools/guest-diag/guest_pin_stream.py
@@ -679,6 +679,42 @@ def resolve_pb_chain(kc, sem, out):
return False
words = struct.unpack_from("<%dQ" % (len(data) // 8), data, 0)
cands = list(dict.fromkeys(w for w in words if is_kern_ptr(w)))
+ # Channel-anchored expansion (r134 live dump): the tracking sem is a
+ # member of a uvm_channel_t table; the channel records sit in the sem's
+ # own window and carry their CE ring GPU VA ([0x121010000, 0x121400000))
+ # plus back-to-back 32-bit object handles. The pool/manager/pushbuffer
+ # pointers hang off those records' targets, which the bare sem-window
+ # scan never reaches - the second-client stall is exactly this: the only
+ # live uvmt event is the spinning sem, and no mem candidate is found
+ # around it. For each ring-VA word, scan the surrounding record for
+ # kptrs, take those targets, and try the chain shape on both. Additive
+ # and bounded; content scoring still decides, so a wrong candidate
+ # cannot shadow the live pages.
+ extra = []
+ for i, w in enumerate(words):
+ if not w or not (0x121010000 <= w < 0x121400000):
+ continue
+ lo = max(0, i - 0x60)
+ hi = min(len(words), i + 0x60)
+ for c in words[lo:hi]:
+ if not is_kern_ptr(c):
+ continue
+ extra.append(c)
+ tgt = kc.read(c, 0x100)
+ if tgt:
+ tw = struct.unpack_from("<%dQ" % (len(tgt) // 8),
+ tgt, 0)
+ for w2 in tw:
+ if is_kern_ptr(w2):
+ extra.append(w2)
+ if len(extra) >= 512:
+ break
+ if extra:
+ head = []
+ for w in extra:
+ if w not in head and w not in cands:
+ head.append(w)
+ cands = head + cands
mems = []
for w in cands[:KC_CHAIN_MAX]:
for mem in _chain_mems_at(kc, w):