From 756fdfd6b2090b731b34846b1b23b726bb3978ec Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 30 Sep 2026 21:11:09 -0400 Subject: sema-svc: rewind replays may only be skipped when their release was delivered The per-put-epoch consumed-slot skip must not suppress a slot whose entry was consumed *without* delivering its release (the CE grace expiry in real mode): the driver-API smoke test's CE pushes are consumed unreadable before their ring pin lands and depend on the pin-batch rewind replaying them once the translation appears. The skip now applies only to slots whose consumption delivered a release: - tail consumption records a slot when the iteration decoded a release (svc_rel_count delta); the sweep-delivered entry_want consume and the fake-release consume always record - the grace-expiry consume records only when a recovery (fake or sema_rel_recover) delivered the release - svc_fake_release counts as a delivered release So real-mode replays still re-process undelivered entries, while the runtime-client case (readable pushes delivered immediately) keeps the fast path that removed the 8 s stalls. --- kernel/gsp_sema_service.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 30c5561..e97c2ff 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -4995,6 +4995,7 @@ static bool svc_fake_release(struct nv_vgpu_device *vgpu, struct svc_channel *ch svc.releases_applied++; } svc.releases_faked++; + svc_rel_count++; ch->expected_sem_payload++; return true; } @@ -5149,6 +5150,9 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) } } + u32 rel_n_iter = svc_rel_count; + + (void)rel_n_iter; if (rrc) { stalled = true; /* ring unreadable: sweep RAM */ break; @@ -5614,7 +5618,10 @@ if (gsp_sema_fake_rel && } ch->rescue_fail = 0; ch->defer_since = 0; - svc_replay_note(ch, idx, put); + if (gsp_sema_fake_rel || + gsp_sema_rel_recover) + svc_replay_note(ch, idx, + put); ch->last_get = (idx + 1) % ch->gpfifo_entries; svc.gpfifo_skipped++; @@ -5650,7 +5657,8 @@ if (gsp_sema_fake_rel && } } - svc_replay_note(ch, idx, put); + if (ch->engine_type && svc_rel_count != rel_n_iter) + svc_replay_note(ch, idx, put); ch->last_get = (idx + 1) % ch->gpfifo_entries; ch->rescue_fail = 0; ch->defer_since = 0; -- cgit v1.2.3