From d94fc701b557c685e07dbc5470f56b3adee89e70 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 30 Sep 2026 20:52:06 -0400 Subject: 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). --- kernel/gsp_sema_service.c | 26 +++++++++++++++++++------- 1 file 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; } -- cgit v1.2.3