From 5bb2d53ec14f0d802726bc879b994c0286f85415 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 8 Oct 2026 04:15:24 -0400 Subject: vgsp+guest-diag: kcore-truth pin resolver (pool/pushbuffer/channel ring+userd) + GR ring userd-derived candidates guest_pin_stream.py now resolves translations entirely from guest truth via /proc/kcore + a manual page-table walk (no QMP races): the CE semaphore pool and pushbuffer memory from the UVM rm_mem structures, and each channel's GPFIFO ring + GPPUT from the tracking semaphore's embedding uvm_channel_t (channel_info located by its gpFifoGpuVa value). This removes the watcher pipeline's flakiness on the cudaMalloc stall class (missing pool/pushbuffer pins). gsp_sema_service.c: svc_gr_ring_autopin tries the guest-registered USERD memdesc base as a ring candidate (the fixed FB convention only matches when the guest's VRAM allocator happens to reproduce the old layout), plus an optional (gsp_sema_dbg) one-shot FB scan + raw-word diagnostics when every candidate fails. tools/cuda-ab/p2: self-checking arbitrary-kernel acceptance suite (10 programs: sequential launches, shapes, params, smem/GEMM, streams, malloc churn, printf+error, FMA benchmark, mixed, managed probe) with host oracle expectations and a guest runner. --- kernel/gsp_sema_service.c | 110 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 3 deletions(-) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 9872fac..dc4b7b1 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -7027,6 +7027,7 @@ static void svc_notify_complete(struct nv_vgpu_device *vgpu, static unsigned long svc_ring_done; /* CE ranks whose ring is pinned */ static unsigned long svc_gr_ring_done; /* GR ranks whose ring is pinned */ +static bool svc_fbs_scan_done; /* one-shot FB entry scan diagnostic */ static u64 svc_gr_ring_base; /* FB offset where GR chunks start */ /* Read and decode the channel's first GPFIFO entry (its first push). */ @@ -7197,6 +7198,58 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu, if (!max_ce) return; /* wait until the CE channels are known */ + /* + * Guest truth first: the channel registration carries the USERD + * memdesc base for THIS session's allocation, and the ring sits one + * USERD block before it (observed for every GR channel across + * boots). The fixed-offset convention below only matches when the + * guest's VRAM allocator happens to place the channel allocation at + * 0x80000 + 0x20000*CE_count; that layout varies per boot (the + * stall class: the convention candidate reads all-zero and the ring + * never resolves, so the client's RM event loop waits forever). + * Deriving the candidate from the registration removes the guess; + * the entry0 + USERD validation stays exactly the same, so a + * wrong derived candidate costs a failed probe, not a wrong pin. + */ + if (ch->userd_pa > SVC_GR_USERD_OFF) { + static const u64 deltas[] = { SVC_GR_USERD_OFF, 0x1000, 0x0, + 0x10000 }; + int cap = ch->userd_as ? ch->userd_as : SVC_APERTURE_SYS; + unsigned int di; + + for (di = 0; di < ARRAY_SIZE(deltas); di++) { + u64 cand = ch->userd_pa - deltas[di]; + + if (ch->userd_pa <= deltas[di]) + continue; + if (svc_read_ap(vgpu, cand, cap, e, sizeof(e))) + continue; + memcpy(&e0, e, 4); + memcpy(&e1, e + 4, 4); + va = ((u64)(e1 & 0xff) << 32) | + (u64)(e0 & 0xfffffffc); + len = ((e1 >> 10) & 0x1fffff) << 2; + if ((va & 0xfffff) || va < SEMA_VA_LO || + va >= SEMA_VA_HI || len < 4 || len > 0x10000) + continue; + if (svc_userd_probe(vgpu, ch->userd_pa, cap, + ch->gpfifo_entries, &put, &get)) + continue; + svc_pin_store(ch->gpfifo_va, cand, cap); + svc_lat_store(ch->gpfifo_va, cand, cap); + ch->userd_as = cap; + ch->userd_ok = true; + svc_gr_ring_base = cand; + set_bit(ch->gr_index, &svc_gr_ring_done); + svc_ring_n++; + pr_info("sema-chan: auto-pinned GR ring h=0x%x rank=%u va=0x%llx -> pa=0x%llx ap=%d (userd-derived d=0x%llx; entry0 va=0x%llx len=%u put=%u get=%u)\n", + ch->h_object, ch->gr_index, + ch->gpfifo_va, cand, cap, deltas[di], va, + len, put, get); + return; + } + } + base = SVC_CE_RING_FB_BASE + SVC_CE_RING_FB_STRIDE * max_ce; pa = base + SVC_GR_RING_STRIDE * ch->gr_index; @@ -7284,9 +7337,60 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu, } } - if (!test_and_set_bit(ch->gr_index, &svc_gr_ring_tried)) - pr_info("sema-chan: GR ring h=0x%x rank=%u not at fb 0x%llx yet (entry e0=0x%x e1=0x%x va=0x%llx len=%u)\n", - ch->h_object, ch->gr_index, pa, e0, e1, va, len); + if (!test_and_set_bit(ch->gr_index, &svc_gr_ring_tried)) { + u8 d1[8] = { 0 }, d2[8] = { 0 }; + int cap = ch->userd_as ? ch->userd_as : SVC_APERTURE_SYS; + u64 w1 = 0, w2 = 0; + u32 p2 = 0, g2 = 0; + int prc; + + if (ch->userd_pa > SVC_GR_USERD_OFF && + !svc_read_ap(vgpu, ch->userd_pa - SVC_GR_USERD_OFF, cap, + d1, sizeof(d1))) + memcpy(&w1, d1, 8); + if (ch->userd_pa && + !svc_read_ap(vgpu, ch->userd_pa, cap, d2, sizeof(d2))) + memcpy(&w2, d2, 8); + prc = ch->userd_pa ? + svc_userd_probe(vgpu, ch->userd_pa, cap, + ch->gpfifo_entries, &p2, &g2) : -1; + pr_info("sema-chan: GR ring h=0x%x rank=%u not at fb 0x%llx yet (e0=0x%x e1=0x%x va=0x%llx len=%u); userd 0x%llx ap=%d w@u-0x2000=0x%llx w@u=0x%llx probe rc=%d put=%u get=%u\n", + ch->h_object, ch->gr_index, pa, e0, e1, va, len, + ch->userd_pa, cap, w1, w2, prc, p2, g2); + + /* One-shot content scan of the emulated VRAM for a GPFIFO + * entry0-shaped word (1 MB aligned push VA, sane length). The + * client's ring allocation offset varies per boot; the scan + * names the real location for the fix. */ + if (gsp_sema_dbg && vgpu->bars[1].vaddr && vgpu->bars[1].size && + !svc_fbs_scan_done) { + u64 lim = min_t(u64, vgpu->bars[1].size, 0x20000000ULL); + u64 off; + int hits = 0; + + svc_fbs_scan_done = true; + for (off = 0; off + 8 <= lim && hits < 40; off += 8) { + u32 h0, h1; + u64 hva; + u32 hlen; + + memcpy(&h0, vgpu->bars[1].vaddr + off, 4); + memcpy(&h1, vgpu->bars[1].vaddr + off + 4, 4); + hva = ((u64)(h1 & 0xff) << 32) | + (u64)(h0 & 0xfffffffc); + hlen = ((h1 >> 10) & 0x1fffff) << 2; + if (!hva || (hva & 0xfffff) || + hva < SEMA_VA_LO || hva >= SEMA_VA_HI || + hlen < 4 || hlen > 0x10000) + continue; + pr_info("sema-chan: fbs scan hit off=0x%llx e0=0x%x e1=0x%x va=0x%llx len=%u\n", + off, h0, h1, hva, hlen); + hits++; + } + pr_info("sema-chan: fbs scan done h=0x%x hits=%d (lim 0x%llx)\n", + ch->h_object, hits, lim); + } + } } static void svc_ring_autopin(struct nv_vgpu_device *vgpu, -- cgit v1.2.3