summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 20:52:06 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 20:52:06 -0400
commitd94fc701b557c685e07dbc5470f56b3adee89e70 (patch)
treeb1cff38ccb3f7836f058d0167f65852b718e0090 /kernel/gsp_sema_service.c
parent37dc6aa328fbb9f2df3e47805775dc32cff0352c (diff)
downloadopen-iov-d94fc701b557c685e07dbc5470f56b3adee89e70.tar.gz
open-iov-d94fc701b557c685e07dbc5470f56b3adee89e70.zip
sema-svc: detect a decoded release by count, not by the (unchanging) VA
The pump decided "this push carried a release" by comparing the last decoded release VA before/after svc_decode_stream. Consecutive pushes on a channel release to the SAME tracking-semaphore VA (UVM's tracker pattern), so every push after the first read as release-less: the entry was held for the full CE grace window (observed: exactly one push consumed per 8 s, gating the whole runtime init; the release itself had already been applied by the decode, only the pump's bookkeeping stalled). svc_rel_count now increments on every decoded release (host sem block, REPORT_SEM block, CE launch-DMA release) and the pump compares counts at all three sites (initial decode, rescue re-route, rescued-page retry).
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index dc8e085..30c5561 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -2534,6 +2534,15 @@ static bool svc_method_stream_plausible(const u8 *buf, u32 len)
* not match the channel rank).
*/
static u64 svc_rel_va_seen;
+/*
+ * Monotonic count of releases decoded. svc_rel_va_seen alone cannot tell
+ * whether a decode produced a release: consecutive pushes on a channel
+ * release to the SAME tracking-semaphore VA (UVM's tracker pattern), so the
+ * VA is unchanged and the pump read "no release" for every push after the
+ * first - holding each one for the full CE grace window. The count changes
+ * on every decoded release regardless of its target.
+ */
+static u32 svc_rel_count;
static u32 svc_dbg_streams;
static void svc_counter_learn(u32 h, u64 sem_va);
@@ -2999,6 +3008,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
st.rel_payload = payload;
st.have_rel = 1;
svc_rel_va_seen = va;
+ svc_rel_count++;
/* The push's work always runs; see the
* REPORT_SEM comment below. */
if (allow_ops && n_ops && !gsp_sema_skip_ops) {
@@ -3082,6 +3092,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
st.rel_payload = st.rs_payload;
st.have_rel = 1;
svc_rel_va_seen = va;
+ svc_rel_count++;
/*
* The push's collected work always runs on
* real hardware; the semaphore release only
@@ -3435,6 +3446,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
} else if (!svc_sem_write(vgpu, sem_va, cur)) {
svc.releases_applied++;
svc_rel_va_seen = sem_va;
+ svc_rel_count++;
svc.post_hint_until = jiffies + 10 * HZ;
}
}
@@ -5213,7 +5225,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
* alias CE encodings.
*/
{
- u64 rel_before = svc_rel_va_seen;
+ u32 rel_n_before = svc_rel_count;
bool rel_seen;
svc.op_tr_pending = 0;
@@ -5244,7 +5256,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
break;
}
ch->op_retry = 0;
- rel_seen = (svc_rel_va_seen != rel_before);
+ rel_seen = (svc_rel_count != rel_n_before);
/*
* A CE push that should carry this
* channel's next tracking release but
@@ -5261,7 +5273,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
*/
if (!rel_seen && ch->engine_type &&
ch->expected_sem_payload) {
- u64 rel2 = svc_rel_va_seen;
+ u32 rel_n2 = svc_rel_count;
if (!svc_rescue_push_page(vgpu, ch, va, len) &&
!svc_read_va_trusted(vgpu, va, pb, len))
@@ -5269,7 +5281,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
len, 0, false,
ch, idx, va, true);
rel_seen =
- (svc_rel_va_seen != rel2);
+ (svc_rel_count != rel_n2);
}
if (rel_seen)
ch->last_rel_va =
@@ -5424,8 +5436,8 @@ if (gsp_sema_fake_rel &&
* the release is applied.
*/
{
- u64 rel_before =
- svc_rel_va_seen;
+ u32 rel_n_before =
+ svc_rel_count;
svc_decode_stream(vgpu, pb,
len, 0,
@@ -5434,7 +5446,7 @@ if (gsp_sema_fake_rel &&
SVC_ENTRY_NONE,
va,
false);
- if (svc_rel_va_seen != rel_before)
+ if (svc_rel_count != rel_n_before)
ch->last_rel_va =
svc_rel_va_seen;
}