summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-08 11:07:42 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-08 11:07:42 -0400
commit54bc80ae33addabc73a5bc1b0881423a63bc9862 (patch)
tree8555a40907d666bb97925d3b78cd6f008c89bfd8 /kernel
parent7ce387f3e3e5aac043b6d46a4451269c2b5c5233 (diff)
downloadopen-iov-54bc80ae33addabc73a5bc1b0881423a63bc9862.tar.gz
open-iov-54bc80ae33addabc73a5bc1b0881423a63bc9862.zip
vgsp-rm: PROMOTE_CTX reply must keep bInitialize set (ISSUE-0001)
kgrobjPromoteContext_IMPL marks each ctx buffer initialized when the REPLY's promoteEntry[i].bInitialize is set: if (!params.promoteEntry[i].bInitialize) continue; kgrctxMarkCtxBufferInitialized(...); The flag is the server's initialized-ACK, so the correct emulation reply is a verbatim echo (the physical backend owns residency; the control answers SUCCESS). 7ce387f3 cleared the flag believing the check inverted - that skipped the mark and left the RM re-promoting the same buffers forever. Restore echo semantics with the source-cited comment.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_rm_emulation.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 2d66912..2ad1ba7 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -3092,40 +3092,59 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
req.paramsSize + GSP_RM_CTRL_HDR_SIZE <=
GSPRM_MAX_SINGLE_ELEM_DATA) {
u8 *rp = reply + GSP_RM_CTRL_HDR_SIZE;
- u32 cleared = 0;
+ u32 init_entries = 0, k;
- 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.
+ * PROMOTE_CTX is an in/out control: the client allocates
+ * one NV2080_CTRL_GPU_PROMOTE_CTX_PARAMS, fills the
+ * entries that still need work (bInitialize=1 for a PA
+ * initialization; the prepare helpers also emit VA
+ * promotion entries), sends it, and reads the SAME
+ * buffer back after the call. The reply decides whether
+ * the client marks the ctx buffer initialized and stops
+ * re-promoting it (kernel_graphics_object.c,
+ * kgrobjPromoteContext_IMPL):
+ *
+ * status = pRmApi->Control(..., &params, ...);
+ * if (status == NV_OK) {
+ * for (i = 0; i < entryCount; ++i) {
+ * if (!params.promoteEntry[i].bInitialize)
+ * continue;
+ * kgrctxMarkCtxBufferInitialized(...,
+ * params.promoteEntry[i].bufferId);
+ * }
+ * }
+ *
+ * The flag is therefore the server's "context buffer is
+ * initialized" acknowledgement: an entry the client
+ * asked to initialize must come back with bInitialize
+ * STILL SET, or the client skips the mark, re-prepares
+ * the same buffer on every pass and the context never
+ * becomes usable. The physical backend owns the actual
+ * residency and the emulation answers SUCCESS, so the
+ * correct reply is a verbatim echo - the request's
+ * flags already carry the values the client checks.
+ * (fa9296af briefly cleared the flag believing the
+ * check was inverted; that made the client re-promote
+ * forever. This is the corrected semantics.)
*/
+ memcpy(rp, pp, req.paramsSize);
if (req.paramsSize >= 48) {
- u32 ec = 0, k;
+ u32 ec = 0;
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 (rp[48 + k * 32 + 30])
+ init_entries++;
}
}
- if (cleared)
+ if (init_entries)
nv_vgpu_info(ctx->vgpu,
- "vgsp-rm: PROMOTE_CTX reply acked init on %u entr%s (bInitialize cleared)",
- cleared, cleared == 1 ? "y" : "ies");
+ "vgsp-rm: PROMOTE_CTX reply confirms %u initialize entr%s (bInitialize kept; client will mark ctx buffers initialized)",
+ init_entries,
+ init_entries == 1 ? "y" : "ies");
}
break;
}