From 4f28cbed07a20b290891e7325a07072326c78167 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 23 Oct 2026 17:51:23 -0400 Subject: vgsp-sema r568: gate a partially-resolved launch on any unexecuted CE write The page-level dstpend guard is blind when the launch's argument base was dropped (GRFILL-DROP): the launch's data set then lacks the buffer's pages. r571 mail: the VADD's copy-in ran at 319818.68 while the b H2D executed at 319820.16 (its base dropped, 9 pages unresolved) - the engine computed c = a + 0 again, same signature as r567/r568. r570 passed only because the page-level guard happened to catch it there. svc_copy_pending(): true when any active opdef slot belongs to a CE channel (a withheld CE release = a device write that has not executed; GR channels excluded so a launch's own withheld release cannot defer itself). A launch that is partially resolved (gr_arg_partial or gr_dropped > 0) now defers while any such write is pending, bounded by the same busy-defer + absolute 15 s cap machinery. Fully-resolved launches are unaffected (the page-level guard already covers them). --- kernel/gsp_sema_service.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 0fc37cd..fbc0772 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -20946,6 +20946,46 @@ static bool svc_gr_dstpend_overlap(void) return false; } +/* + * r568: a CE channel entry with a withheld release is a device write that + * has NOT executed yet. A GR launch must not read any of the client's + * device pages while such a write is pending. The page-level dstpend guard + * cannot cover this when the launch's argument base was dropped + * (GRFILL-DROP): the launch's data set then does not contain the buffer's + * pages, so the overlap check is blind to them - the r571 mail VADD read b + * 1.5 s before the b H2D executed (copy-in 319818.68, b copy 319820.16) and + * computed c = a + 0. Gate the launch on the coarser but complete + * condition: any active opdef slot whose channel is a CE channel means at + * least one copy/fill is unexecuted. Bounded by the same busy-defer + + * absolute 15 s cap machinery as every other guard, so a genuinely stuck + * copy delays a launch by the cap and no more. GR channels are excluded + * (a launch's own withheld release must not defer itself). + */ +static bool svc_copy_pending(void) +{ + unsigned long flags; + bool pending = false; + u32 i, c; + + for (i = 0; i < SVC_OPDEF_SLOTS && !pending; i++) { + struct svc_opdef_ent *e = &svc_opdef[i]; + + if (!e->active || !e->n) + continue; + spin_lock_irqsave(&svc.chan_lock, flags); + for (c = 0; c < SVC_MAX_CHANNELS; c++) + if (svc.chan[c].valid && + svc.chan[c].vgpu == e->vgpu && + svc.chan[c].h_object == e->h_object) { + if (svc.chan[c].engine_type) + pending = true; + break; + } + spin_unlock_irqrestore(&svc.chan_lock, flags); + } + return pending; +} + static bool svc_gr_request(struct nv_vgpu_device *vgpu, const struct svc_channel *ch) { @@ -21070,6 +21110,26 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu, } return false; } + /* + * r568: the coarse companion gate - any unexecuted CE write at all + * (see svc_copy_pending). Covers the dropped-argument-base case the + * page-level guard cannot see (the r571 mail b-copy). + */ + if (svc_copy_pending() && + (svc_fwd_req.gr_arg_partial || svc_fwd_req.gr_dropped > 0) && + !svc_gr_defer_expired(svc_gr_cand.push_va)) { + clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state); + mutex_unlock(&svc_fwd_lock); + svc_gr_busy_defer = true; + svc.fwd_gr_refused++; + svc.fwd_gr_dstpend++; + if (svc.fwd_gr_dstpend_log < 32) { + svc.fwd_gr_dstpend_log++; + pr_info("vgsp-work: GR forward deferred h=0x%x push=0x%llx (a CE write is unexecuted; bounded retry)\n", + ch->h_object, svc_gr_cand.push_va); + } + return false; + } /* * r543: a partially-resolved ARGUMENT set must not forward either - * the engine would run with a stale/zero operand (the r542 matmul -- cgit v1.2.3