summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c42
-rw-r--r--tools/guest-diag/guest_pin_stream.py24
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: