diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 20:52:06 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 20:52:06 -0400 |
| commit | 662d3d49d6d43b33da72196d6e1060ed7cc043ab (patch) | |
| tree | ead3a31a3d3e11d4ddd8080004032291a6c13b4c /kernel/gsp_sema_service.c | |
| parent | 83ded3466f0f6367387be6c74dbeea9fe0e661f8 (diff) | |
| download | open-iov-662d3d49d6d43b33da72196d6e1060ed7cc043ab.tar.gz open-iov-662d3d49d6d43b33da72196d6e1060ed7cc043ab.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.c | 26 |
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; } |
