summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-09 21:16:49 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-09 21:16:49 -0400
commitb021abb242664d0c4cb2492c5d73aa7bdcdee4c4 (patch)
treeb9c4d2922a351c07266f4ae36407af5f7abcdf92
parent22238ebd3cfc6e568049cdd73773fb842ea41565 (diff)
downloadopen-iov-b021abb242664d0c4cb2492c5d73aa7bdcdee4c4.tar.gz
open-iov-b021abb242664d0c4cb2492c5d73aa7bdcdee4c4.zip
vgsp-sema: re-seed and apply the first release of a fresh CE channel when the pool word is residue (ISSUE-0002)
A fresh session's first CE release could read a previous session's value through the just-injected pool pin (r64: cur=134 pay=1; r63: cur=114696). svc_init_expected_payload seeded the channel expectation from that residue, the release candidate then skipped as stale (payload <= cur) and the client's first tracker wait never completed. When the first GPFIFO entry of a fresh CE channel (submissions == 0) decodes a pool release whose word reads ahead of the payload, treat the word as residue: re-seed expected_sem_payload/entry_want from the payload and apply the release absolute instead of skipping. Monotonic trackers make the absolute write idempotent; displaced pins stay owned by the fan-out/pending paths. Bounded 'sema-chan: pool residue' diagnostic plus a residue counter in the drain line.
-rw-r--r--kernel/gsp_sema_service.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 77a1fae..d69be19 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -573,6 +573,14 @@ struct sema_svc {
u64 sem_write_reresolve; /* writes re-resolved after read-back */
u64 pool_alt_applied; /* pool releases fanned to a
* displaced pin (ISSUE-0002) */
+ u64 pool_residue; /* fresh-channel first releases whose
+ * pool word read far ahead of the
+ * payload (previous session's
+ * value in a reused pool page);
+ * re-seeded from the payload and
+ * applied instead of skipped as
+ * stale (ISSUE-0002 r63/r64) */
+ u64 pool_residue_log; /* residue diagnostic budget */
u64 pushpg_fallback; /* injected pin rejected by content */
u64 gpfifo_skipped; /* stale entries consumed */
u64 gpfifo_rescued; /* unreadable push made readable
@@ -3287,10 +3295,10 @@ static void svc_rebuild(struct nv_vgpu_device *vgpu)
svc.releases_faked, svc.releases_recovered,
svc.ops_once_skipped, svc.ops_reident,
svc.opdef_held, svc.opdef_applied, svc.opdef_expired);
- pr_info("sema-svc: counter pub_calls=%llu gr_rel=%llu reresolve=%llu pushpg_fb=%llu altw=%llu\n",
+ pr_info("sema-svc: counter pub_calls=%llu gr_rel=%llu reresolve=%llu pushpg_fb=%llu altw=%llu residue=%llu\n",
svc.counter_pub_calls, svc.gr_rel_applied,
svc.sem_write_reresolve, svc.pushpg_fallback,
- svc.pool_alt_applied);
+ svc.pool_alt_applied, svc.pool_residue);
if (svc.resc_run)
pr_info("sema-svc: rescue_run=%llu (multi-page content pins)\n",
svc.resc_run);
@@ -6495,6 +6503,61 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
DMA_SEM_REDUCTION(dma) ==
SEM_REDUCTION_INC) ? 1 : 0);
} else if (svc_pool_sem_va(sem_va) &&
+ ch && ch->engine_type &&
+ !ch->submissions &&
+ cur > st.sem_payload) {
+ /*
+ * ISSUE-0002 (r63/r64): the
+ * first GPFIFO entry of a
+ * fresh CE channel carries
+ * the release that starts
+ * the channel's tracker.
+ * When the pool word
+ * already reads far ahead
+ * of the decoded payload
+ * through the injected pin,
+ * the word cannot be this
+ * session's live tracker
+ * (no entry of this channel
+ * has executed yet): it is
+ * the previous session's
+ * value in a reused pool
+ * page. svc_init_expected_
+ * payload seeded the
+ * expectation from that
+ * residue, so the release
+ * was skipped as stale
+ * (payload <= cur) and the
+ * client's first tracker
+ * wait never completed
+ * (r64: cur=134, pay=1;
+ * r63: cur=114696).
+ * Re-seed the expectation
+ * from the payload and
+ * apply it absolute: for a
+ * monotonic tracker that is
+ * the exact value the
+ * client polls, and the
+ * fan-out/pending paths
+ * still own any displaced
+ * pin.
+ */
+ ch->expected_sem_payload =
+ st.sem_payload;
+ ch->entry_want = st.sem_payload;
+ have_cur = true;
+ pending = 1;
+ svc.pool_residue++;
+ if (svc.pool_residue_log < 32) {
+ svc.pool_residue_log++;
+ pr_info("sema-chan: pool residue h=0x%x rank=%u va=0x%llx pay=%u cur=%u -> re-seed + apply (fresh channel)\n",
+ ch->h_object,
+ ch->ce_index,
+ sem_va,
+ st.sem_payload,
+ cur);
+ }
+ } else if (svc_pool_sem_va(sem_va) &&
(svc_pool_hold_active() || !cur)) {
/*
* A readable pool word of 0