summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-16 21:05:05 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-16 21:05:05 -0400
commitf2a4adc091a43d73eca4388df84fd1a67fb4007f (patch)
tree8f4e469de9553489fc0ce6571243cd086369c42d /kernel/gsp_sema_service.c
parentb90ced5aa52d202e678918093d1bb497ec1efd2b (diff)
downloadopen-iov-f2a4adc091a43d73eca4388df84fd1a67fb4007f.tar.gz
open-iov-f2a4adc091a43d73eca4388df84fd1a67fb4007f.zip
vgsp: m167 session flush never wipes a live session (r169: deferred flush fired with smiley's channels live 7s after registration, dropped its queued launch release, client spun in uvm_channel_is_value_completed) + m164 hardening: GR no-capture hold applies only to fresh entries, never replays (old-session pushes were held and re-counted)
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index d6b9617..ad03f5f 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -7335,6 +7335,35 @@ static void svc_session_flush(void)
unsigned long flags;
u32 i;
+ /*
+ * m167: never wipe a LIVE session. The flush is requested when a
+ * channel close leaves the table empty, but that transition fires
+ * during ordinary UVM channel cycling and the deferred execution can
+ * land after the same client (or the next client, when its chan_add
+ * raced the requested flush) has registered channels again - r169:
+ * the flush executed 2.5 s after smiley's launch with its channels
+ * live (registered 7 s earlier), wiped the queued completion releases,
+ * and the client spun forever in uvm_channel_is_value_completed
+ * (release never applied; pool word frozen). A live channel's session
+ * owns the tables - skipping is always safe because a genuine session
+ * end re-arms the flush when its own channels close.
+ */
+ {
+ bool live = false;
+
+ spin_lock_irqsave(&svc.chan_lock, flags);
+ for (i = 0; i < SVC_MAX_CHANNELS; i++)
+ if (svc.chan[i].valid) {
+ live = true;
+ break;
+ }
+ spin_unlock_irqrestore(&svc.chan_lock, flags);
+ if (live) {
+ pr_info("sema-svc: session flush skipped: live channel(s) present (deferred flush raced a new session registration)\n");
+ return;
+ }
+ }
+
svc_gr_diag_reset(); /* m150: per-session diagnostic budgets */
svc.map_n = 0;
svc_pb_n = 0;
@@ -14899,6 +14928,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
if (!ch->engine_type && va && len &&
gsp_phys_gr_forward_enabled() &&
svc_gr_qmd_seen > 0 &&
+ !entry_replay &&
!(svc_gr_cand.valid &&
svc_gr_cand.h_object ==
ch->h_object &&