diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-12 17:26:11 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-12 17:26:11 -0400 |
| commit | ade77d9a5f80cb54dc8587f75e066679ca98884e (patch) | |
| tree | 972cca9b952b7f4250a67a4189322c0a26399748 | |
| parent | bb5397afd7afcb97865508ff8c23963ffcd5334f (diff) | |
| download | open-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.
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 36 |
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): |
