diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-09 10:36:40 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-09 10:36:40 -0400 |
| commit | f5f9d31ed0bd1b7e08b1072ef83ed41d743bbd91 (patch) | |
| tree | cbd434237e9c6ace367612c59e05c2880cde02fd /kernel | |
| parent | 01b7626a6ef10da3f29e0d322b281d941c4b3d51 (diff) | |
| download | open-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.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 32 |
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 |
