diff options
| -rw-r--r-- | kernel/gsp_sema_service.c | 42 | ||||
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 24 |
2 files changed, 57 insertions, 9 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 21f0de0..e336277 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -351,6 +351,8 @@ struct sema_svc { u64 releases_jumped; /* applied with gap > 1 */ u64 releases_faked; /* skipped-entry fallback */ u64 counter_rel_applied; /* releases to registered counters */ + u64 counter_rel_dbg; /* rel-apply diagnostic budget */ + u64 counter_pub_dbg; /* counter-publish diagnostic budget */ u64 counter_pub_calls; /* publishes that found a registered counter */ u64 gr_rel_applied; /* release writes into the GR counter page */ u64 gr_rel_log; @@ -2107,6 +2109,7 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h, u64 pa = 0; u32 cur = 0; int i; + u32 dbg = 0; if (!h || !payload) return; @@ -2119,21 +2122,43 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h, } } spin_unlock_irqrestore(&svc.chan_lock, flags); - if (!pa) + if (!pa) { + if (svc.counter_rel_dbg < 32) { + svc.counter_rel_dbg++; + pr_info("sema-chan: rel-apply h=0x%x pay=%u -> no slot registered\n", + h, payload); + } return; + } - if (svc_read_ap(vgpu, pa, SVC_APERTURE_SYS, &cur, sizeof(cur))) + if (svc_read_ap(vgpu, pa, SVC_APERTURE_SYS, &cur, sizeof(cur))) { + if (svc.counter_rel_dbg < 32) { + svc.counter_rel_dbg++; + pr_info("sema-chan: rel-apply h=0x%x pa=0x%llx pay=%u -> read failed\n", + h, pa, payload); + } return; - if (payload <= cur || payload - cur > 0x100000) + } + if (payload <= cur || payload - cur > 0x100000) { + if (svc.counter_rel_dbg < 32) { + svc.counter_rel_dbg++; + pr_info("sema-chan: rel-apply h=0x%x pa=0x%llx pay=%u cur=%u -> skip\n", + h, pa, payload, cur); + } return; + } if (svc_write_ap(vgpu, pa, SVC_APERTURE_SYS, &payload, sizeof(payload))) return; svc.releases_applied++; svc.counter_rel_applied++; svc.post_hint_until = jiffies + 10 * HZ; - pr_info_ratelimited("sema-chan: counter release h=0x%x pa=0x%llx val=%u (was %u)\n", - h, pa, payload, cur); + if (svc.counter_rel_dbg < 32) { + svc.counter_rel_dbg++; + pr_info("sema-chan: rel-apply h=0x%x pa=0x%llx pay=%u cur=%u -> written\n", + h, pa, payload, cur); + } + (void)dbg; } /* @@ -3966,8 +3991,11 @@ static void svc_counter_publish(struct nv_vgpu_device *vgpu, &val, sizeof(val))) return; ch->counter_last = val; - pr_info_ratelimited("sema-chan: counter publish h=0x%x pa=0x%llx val=%u\n", - ch->h_object, ch->counter_pa, val); + if (svc.counter_pub_dbg < 48) { + svc.counter_pub_dbg++; + pr_info("sema-chan: counter publish h=0x%x pa=0x%llx val=%u (was %u)\n", + ch->h_object, ch->counter_pa, val, cur); + } } /* diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index 8d0b34d..717a05d 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -141,6 +141,26 @@ def main(): time.sleep(INTERVAL) continue dt = time.time() - t0 + # Diagnostic: the GR completion-counter page is the one page the + # client's context-init wait polls; log its pagemap entry every loop + # so a scan blind spot is visible in the guest log. + cpm = None + try: + fdp = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY) + os.lseek(fdp, (0x20400fec0 // 4096) * 8, 0) + cpm = int.from_bytes(os.read(fdp, 8), 'little') + os.close(fdp) + except OSError: + cpm = None + diag = ('cpm=%s' % ('present' if (cpm or 0) >> 63 & 1 else 'absent') + if cpm is not None else 'cpm=ERR') + # Guaranteed fast path for the GR completion-counter page: if the + # window scan misses it (observed once), add it explicitly so the host + # can register the slots before the client's first wait. + if cpm is not None and (cpm >> 63) & 1: + cpa = (cpm & ((1 << 55) - 1)) << 12 + if cpa and (not PAMAX or cpa < PAMAX): + cur[0x20400f000] = cpa new = [(va, pa) for va, pa in cur.items() if seen.get(va) != pa] seen = cur lines = [] @@ -152,9 +172,9 @@ def main(): last_log = now try: with open('/tmp/guest_pin_stream.log', 'a') as f: - f.write('%s pid=%s present=%d new=%d sem=%d scan=%.3fs\n' + f.write('%s pid=%s present=%d new=%d sem=%d scan=%.3fs %s\n' % (time.strftime('%T'), pid, len(cur), len(new), - len(seen_sems), dt)) + len(seen_sems), dt, diag)) except OSError: pass if not new and not lines: |
