summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index d69be19..075a429 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -168,6 +168,18 @@ struct svc_channel {
* last_get to slot 0 so the live first push is
* processed instead of skipped. */
bool logged; /* one state log per channel */
+ bool pool_rel_seen; /* ISSUE-0002 r70: a pool release word for
+ * this channel has been read through a
+ * translated source at least once in this
+ * session. The residue rule (first release of
+ * a fresh channel whose word reads far ahead
+ * of the payload) must fire on the FIRST
+ * translated read only: the rescue path can
+ * consume entry 0 (submissions++) before the
+ * pool pin lands, the pin batch then rewinds
+ * last_get, and the re-decode is no longer a
+ * fresh channel by submissions - but it still
+ * is by this flag. */
u64 instance_pa;
u64 notifier_pa; /* error notifier: NvNotification slots */
u32 notifier_as;
@@ -6504,7 +6516,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
SEM_REDUCTION_INC) ? 1 : 0);
} else if (svc_pool_sem_va(sem_va) &&
ch && ch->engine_type &&
- !ch->submissions &&
+ !ch->pool_rel_seen &&
cur > st.sem_payload) {
/*
* ISSUE-0002 (r63/r64): the
@@ -6589,6 +6601,19 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
if (st.sem_payload > cur)
pending = 1;
}
+ /*
+ * ISSUE-0002 r70: the residue rule
+ * applies to the first translated
+ * pool read of the session only.
+ * The rescue path can consume entry 0
+ * before the pool pin lands and the
+ * pin batch then rewinds last_get,
+ * so a submissions-based freshness
+ * test misses the re-decode; this
+ * flag does not.
+ */
+ if (!rrc2 && svc_pool_sem_va(sem_va) && ch)
+ ch->pool_rel_seen = true;
}
/*
@@ -14359,6 +14384,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
bitmap_copy(svc.chan[k].rel_done, ch->rel_done,
SVC_GPFIFO_MAX_BITS);
svc.chan[k].last_rel_va = ch->last_rel_va;
+ svc.chan[k].pool_rel_seen = ch->pool_rel_seen;
svc.chan[k].rescue_last = ch->rescue_last;
svc.chan[k].rescue_fail = ch->rescue_fail;
svc.chan[k].push_hold_until = ch->push_hold_until;