From 79e1f459301849e57baffc0e796df32b2aeb8124 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 16 Oct 2026 14:18:32 -0400 Subject: vgsp-sema: m157 defer busy-refused GR captures instead of soft-releasing them (R1) r157 streams2: kernels 2 and 3 were captured while kernel 1's forward was INFLIGHT, refused by svc_gr_request, and their releases were fabricated in software 36 us later (the F2.3 fail-open path) - the client read all zeros. Now a busy refusal (hold active / INFLIGHT / paused, bridge disabled) sets svc_gr_busy_defer and the entry loop holds the entry under the m150 one-shot window instead of consuming it, so the pump re-captures and forwards it for real once the in-flight launch completes. With the bridge enabled the old behaviour is kept (the bridge job owns the release). --- kernel/gsp_sema_service.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 31d5d82..79807ab 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -12572,6 +12572,14 @@ static bool svc_gr_page_inline_covers(u64 page) static u32 svc_gr_data_log; /* m142: bounded per-page attribution log */ static u32 svc_gr_src_log; /* m150: bounded per-candidate source log */ static bool svc_gr_data_stalled; /* m150: high data args unresolved */ +/* + * m156 (R1): the GR request was refused because a forward was already + * in flight (or a release hold was active) - the launch COULD run later, so + * the entry must be deferred, not consumed with a fabricated software + * release. r157 streams2: kernels 2 and 3 were refused-while-busy (kernel 1 + * in flight) and soft-released 36 us later; the client read all zeros. + */ +static bool svc_gr_busy_defer; static u64 svc_gr_hold_log; /* m150: bounded GR-hold proof lines */ /* m150: re-arm both fill diagnostics for each client session. */ @@ -13169,6 +13177,9 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu, { int rc; + /* m156: never let a previous call's busy verdict leak into an early + * (candidate-mismatch) return; only the busy paths below set it. */ + svc_gr_busy_defer = false; /* * The candidate is per-channel: a capture left unconsumed by an * earlier pass (e.g. the entry was held before its request) must never @@ -13191,6 +13202,7 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu, * request's done/hw_rc are still being read. The capture falls back. */ if (svc_fwd_hold.active) { + svc_gr_busy_defer = !gsp_cuda_bridge_enabled(); svc.fwd_gr_refused++; svc.fwd_gr_fallback++; svc_gr_bridge_fallback(vgpu); @@ -13200,6 +13212,7 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu, if (svc_fwd_paused || test_and_set_bit_lock(SVC_FWD_INFLIGHT, &svc_fwd_state)) { mutex_unlock(&svc_fwd_lock); + svc_gr_busy_defer = !gsp_cuda_bridge_enabled(); svc.fwd_gr_refused++; svc.fwd_gr_fallback++; svc_gr_bridge_fallback(vgpu); @@ -14508,7 +14521,8 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) */ if (!fwd_guest_queued && !ch->engine_type && - svc_gr_data_stalled && + (svc_gr_data_stalled || + svc_gr_busy_defer) && ch->gr_hold_idx != (u32)idx) { u32 hold_ms = gsp_sema_gr_grace_ms ? gsp_sema_gr_grace_ms : 8000; @@ -14519,9 +14533,13 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) svc.fwd_gr_defer++; if (svc_gr_hold_log < 16) { svc_gr_hold_log++; - pr_info("sema-svc: GR hold h=0x%x entry=%u (data args unresolved; retry window %u ms)\n", + pr_info("sema-svc: GR hold h=0x%x entry=%u (%s; retry window %u ms)\n", ch->h_object, - (u32)idx, hold_ms); + (u32)idx, + svc_gr_data_stalled ? + "data args unresolved" : + "forward busy (m156)", + hold_ms); } kfree(pb); break; -- cgit v1.2.3