summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-09 10:36:40 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-09 10:36:40 -0400
commitf5f9d31ed0bd1b7e08b1072ef83ed41d743bbd91 (patch)
treecbd434237e9c6ace367612c59e05c2880cde02fd
parent01b7626a6ef10da3f29e0d322b281d941c4b3d51 (diff)
downloadopen-iov-f5f9d31ed0bd1b7e08b1072ef83ed41d743bbd91.tar.gz
open-iov-f5f9d31ed0bd1b7e08b1072ef83ed41d743bbd91.zip
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.
-rw-r--r--kernel/gsp_sema_service.c32
1 files changed, 32 insertions, 0 deletions
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
@@ -4643,6 +4643,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
* leaves the client's tracker polling a value that never