From f5f9d31ed0bd1b7e08b1072ef83ed41d743bbd91 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 9 Oct 2026 10:36:40 -0400 Subject: vgsp-sema: never drop a decoded pool release in the counter path (ISSUE-0002) A CE (pool) release that reaches svc_counter_release_apply finds no counter slot and was discarded. The launch path normally writes pool releases via svc_sem_write, but skips it whenever it believes the value was already applied (or the word was unreadable at decode time); the second session's early releases were lost exactly there. Apply forward-only absolute through the pool writer instead - idempotent for a monotonic tracker, so a duplicate can never double-count. --- kernel/gsp_sema_service.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index d9c1387..1c6c41a 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -4642,6 +4642,38 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h, } spin_unlock_irqrestore(&svc.chan_lock, flags); if (!pa) { + /* + * Pool (UVM tracking) semaphores have no counter slot. The + * launch path normally writes them through the generic pool + * resolver, but it skips the write whenever it believes the + * release was already applied (or the word was unreadable at + * decode time). A decoded pool release must never be dropped + * here: apply it forward-only absolute through the pool + * writer - writing the payload when it is ahead of the word + * is idempotent for a monotonic tracker, so a duplicate can + * never double-count (ISSUE-0002: second-session releases + * were lost here and the guest waited forever). + */ + if (svc_pool_sem_va(sem_va)) { + u32 pcur = 0; + int wrc; + + if (svc_sem_read(vgpu, sem_va, &pcur)) + return; + if (payload <= pcur) + return; + wrc = svc_sem_write(vgpu, h, sem_va, payload); + if (!wrc) { + svc.releases_applied++; + svc.post_hint_until = jiffies + 10 * HZ; + if (gsp_sema_dbg && svc.counter_rel_dbg < 256) { + svc.counter_rel_dbg++; + pr_info("sema-chan: rel-apply h=0x%x va=0x%llx pay=%u cur=%u -> pool rescue\n", + h, sem_va, payload, pcur); + } + } + return; + } /* * Still no slot: remember the payload so the slot * registration (learn/auto/publish) flushes it. Dropping it -- cgit v1.2.3