From 7ce387f3e3e5aac043b6d46a4451269c2b5c5233 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 8 Oct 2026 10:03:19 -0400 Subject: vgsp-rm: PROMOTE_CTX reply acknowledges ctx-buffer initialization kgrobjPromoteContext_IMPL marks a context buffer initialized only when the REPLY's promoteEntry[i].bInitialize is clear; echoing the request back kept the flag set so the RM re-promoted the same contexts indefinitely. Clear the flag on the echoed reply (per-entry, 5 entries observed per call). Note: this aligns the reply with the caller contract but did NOT by itself unblock the observed cudaMalloc stall (client still reaches DEVICE then spins; zero GR ring content in VRAM) - kept because the old behavior was wrong and the flag gates kgrctxMarkCtxBufferInitialized. --- kernel/gsp_rm_emulation.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 983fecb..2d66912 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -3090,9 +3090,43 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, out_params_size = req.paramsSize; if (req.paramsSize && req.paramsSize + GSP_RM_CTRL_HDR_SIZE <= - GSPRM_MAX_SINGLE_ELEM_DATA) - memcpy(reply + GSP_RM_CTRL_HDR_SIZE, pp, - req.paramsSize); + GSPRM_MAX_SINGLE_ELEM_DATA) { + u8 *rp = reply + GSP_RM_CTRL_HDR_SIZE; + u32 cleared = 0; + + memcpy(rp, pp, req.paramsSize); + /* + * The caller (kgrobjPromoteContext_IMPL) marks each ctx + * buffer initialized ONLY when the REPLY's bInitialize is + * clear: + * if (!params.promoteEntry[i].bInitialize) + * continue; + * kgrctxMarkCtxBufferInitialized(...); + * Echoing the request back keeps bInitialize set forever, + * so the RM re-promotes the same context on every pass and + * never submits the channel's first work (the client's + * CUDA init then spins with an empty GR ring). Clear the + * flag on the reply to acknowledge the (host-side) + * initialization. + */ + if (req.paramsSize >= 48) { + u32 ec = 0, k; + + memcpy(&ec, pp + 40, 4); + for (k = 0; k < ec && + 48u + (k + 1u) * 32u <= req.paramsSize; + k++) { + if (rp[48 + k * 32 + 30]) { + rp[48 + k * 32 + 30] = 0; + cleared++; + } + } + } + if (cleared) + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: PROMOTE_CTX reply acked init on %u entr%s (bInitialize cleared)", + cleared, cleared == 1 ? "y" : "ies"); + } break; } -- cgit v1.2.3