From 3f892b2924c0bdd15aaa04899b879601bd263981 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 6 Oct 2026 11:57:33 -0400 Subject: vgsp: golden-exec shape bisection + fwclient per-entry promotion + pool-VA stall fix - Mode 28 golden execution lane behind gsp_phys_rmcall_gr_promote=28 with a shape bitmask (gsp_phys_rmcall_golden_exec_shape: ring / entries=8 / sysmem USERD / USERD size / hObjectBuffer=VAS / skip replay TURING_A) and a USERD control-offset helper. Finding: the RM-managed golden channel hangs any GR object construct (-110, no assert) as soon as client submission wiring (ring or sysmem USERD) is attached, so only the captured server-owned shape constructs; the machinery is kept for future wiring ideas. - fwclient mask bit 11 (0x800): send each non-MAIN FWCLIENT promote entry as its own one-entry control and continue past refusals. V6 acceptance matrix: PM, PATCH, PRIV_ACCESS_MAP, UNRESTRICTED_PRIV_ACCESS_MAP accepted, FECS_EVENT refused 0x1f. - fwclient mask bit 12 (0x1000): golden9 VA-only global bookings (BUNDLE_CB, PAGEPOOL, ATTRIBUTE_CB, RTV_CB_GLOBAL) accepted on V6; bits 13/14 (0x2000/0x4000): FECS PA-only (refused 0x1f) and FECS VA-only (accepted). - gsp_phys_rmcall_srv_main_ignore: ignore a server-reported MAIN in the srv-ctx commit and force the client INITIALIZE_CTX + VA-only fallback. - gsp_sema_service: pool semaphores never fall back to the learned map; queue the absolute release via svc_pending_add until svc_pool_pa_resolve succeeds, and judge pool slots through the verified resolver in svc_apply_pending and the release decode (UVM registration stall fix). --- kernel/gsp_sema_service.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index a5f58db..2c6836f 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -2316,6 +2316,8 @@ static int svc_sem_read(struct nv_vgpu_device *vgpu, u64 va, u32 *val) return svc_read_ap(vgpu, addr, svc_ap_of(ap), val, sizeof(*val)); } +static void svc_pending_add(u64 va, u32 payload, u32 op); + static int svc_sem_write(struct nv_vgpu_device *vgpu, u32 h, u64 va, u32 val) { u64 addr = 0, old_addr; @@ -2335,10 +2337,25 @@ static int svc_sem_write(struct nv_vgpu_device *vgpu, u32 h, u64 va, u32 val) * historical order below. */ if (is_pool) { - if (!svc_pool_pa_resolve(vgpu, h, va, &addr, &ap, &src)) + if (!svc_pool_pa_resolve(vgpu, h, va, &addr, &ap, &src)) { verified = true; - else + } else { + /* + * A pool semaphore must never be written through the + * learned/content-scanned map: a stale PA there is + * silently lost (observed PA==VA fallback writes) + * while the client polls the real slot forever. The + * exact slot is known from the decoded release, so + * queue the absolute target for the retry pass until + * the verified resolver (pin -> read-back cache -> + * walk -> targeted rm_mem with read-back) can + * translate it. svc_apply_pending() retries every + * service pass and drops the entry once it lands. + */ svc_pool_pa_miss_note(va); + svc_pending_add(va, val, 0); + return -ENOENT; + } } if (!verified && svc_resolve_va(vgpu, va, &addr, &ap)) { /* @@ -5579,7 +5596,27 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (st.have_sem && st.sem_payload && sem_va >= SEMA_VA_LO && sem_va < SEMA_VA_HI) { - if (svc_sem_read(vgpu, sem_va, &cur)) { + int rrc2; + + if (svc_pool_sem_va(sem_va)) { + u64 ppa = 0; + int pap = SVC_APERTURE_SYS; + + if (svc_pool_pa_resolve(vgpu, + ch->h_object, + sem_va, &ppa, + &pap, NULL)) + rrc2 = -ENOENT; + else + rrc2 = svc_read_ap(vgpu, ppa, + svc_ap_of(pap), + &cur, + sizeof(cur)); + } else { + rrc2 = svc_sem_read(vgpu, sem_va, + &cur); + } + if (rrc2) { svc.pushes_nomap++; /* * The semaphore page has no @@ -5826,7 +5863,27 @@ static void svc_apply_pending(struct nv_vgpu_device *vgpu) struct svc_pending_release *p = &svc_pending[i]; u32 cur = 0; - if (svc_sem_read(vgpu, p->va, &cur)) { + if (svc_pool_sem_va(p->va)) { + u64 ppa = 0; + int pap = SVC_APERTURE_SYS; + + /* + * Judge a pool semaphore only through the verified + * resolver: the learned map can answer with a stale + * page whose value makes this release look already + * delivered and drops it (see svc_sem_write). + */ + if (svc_pool_pa_resolve(vgpu, 0, p->va, &ppa, &pap, + NULL)) { + i++; /* not translatable yet: keep */ + continue; + } + if (svc_read_ap(vgpu, ppa, svc_ap_of(pap), &cur, + sizeof(cur))) { + i++; + continue; + } + } else if (svc_sem_read(vgpu, p->va, &cur)) { i++; /* translation still missing: keep waiting */ continue; } -- cgit v1.2.3