summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-16 14:18:32 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-16 14:18:32 -0400
commit79e1f459301849e57baffc0e796df32b2aeb8124 (patch)
tree6d1ee42a147f22a4681b72070a0a7d6799d4b8ab
parenta8d816cda07935fe7bd31215b0edd6caf722c412 (diff)
downloadopen-iov-79e1f459301849e57baffc0e796df32b2aeb8124.tar.gz
open-iov-79e1f459301849e57baffc0e796df32b2aeb8124.zip
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).
-rw-r--r--kernel/gsp_sema_service.c24
1 files changed, 21 insertions, 3 deletions
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;