summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 5f8bf07..d3f73c4 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -6291,6 +6291,32 @@ module_param_named(sema_gl_shsurf_dbg, gsp_sema_gl_shsurf_dbg,
MODULE_PARM_DESC(sema_gl_shsurf_dbg,
"Log every candidate VAS translation for the GLX shared-surface refCount sync (bounded)");
+/*
+ * r1780 (CONT.430g): the shared-surface deadlock. The GLX client writes
+ * lastKickoffRefCount during its GL init (before its first kick), while the
+ * X DDX is already polling gpuRefCount against that same value. If a previous
+ * client left gpuRefCount lower, the DDX waits for a release that the client
+ * will only emit after the very GLX request the DDX is blocking. Sync the
+ * known shared-surface VA to the client's lkr once per second (and on a
+ * manual kick) so the wait clears and the client can proceed to kick.
+ * The VA is the release target observed across boots; the strict lkr gate
+ * (high dword zero, small, cur < lkr) keeps it harmless if the VA maps
+ * something else or the client is not at the surface.
+ */
+static bool gsp_sema_gl_shsurf_watch = true;
+module_param_named(sema_gl_shsurf_watch, gsp_sema_gl_shsurf_watch,
+ bool, 0644);
+MODULE_PARM_DESC(sema_gl_shsurf_watch,
+ "Periodically sync the known GLX shared-surface VA to the client's lastKickoffRefCount; default 1");
+
+static bool gsp_sema_gl_shsurf_kick;
+module_param_named(sema_gl_shsurf_kick, gsp_sema_gl_shsurf_kick,
+ bool, 0644);
+MODULE_PARM_DESC(sema_gl_shsurf_kick,
+ "Write 1 to run the shared-surface sync immediately on the service thread");
+
+#define SVC_GLSHSURF_VA 0x420a00800ULL
+
static bool svc_gl_shsurf_sync(struct nv_vgpu_device *vgpu, u32 h, u64 va,
u32 val)
{
@@ -43198,6 +43224,24 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc_xvas_pdb_discover(vgpu, svc_pdb_disc_va,
svc_pdb_disc_pa);
}
+ /*
+ * r1780 (CONT.430g): clear the GLX shared-surface deadlock before the
+ * channel loop (see the sema_gl_shsurf_watch comment).
+ */
+ {
+ static unsigned long watch_at;
+ u64 sva = svc_gl.rel_va ? svc_gl.rel_va : SVC_GLSHSURF_VA;
+
+ if ((gsp_sema_gl_shsurf_watch || gsp_sema_gl_shsurf_kick) &&
+ time_after(jiffies, watch_at)) {
+ watch_at = jiffies + HZ;
+ gsp_sema_gl_shsurf_kick = false;
+ (void)svc_gl_shsurf_sync(vgpu, 0, sva, 0);
+ if (sva != SVC_GLSHSURF_VA)
+ (void)svc_gl_shsurf_sync(vgpu, 0,
+ SVC_GLSHSURF_VA, 0);
+ }
+ }
/* Only ever called from the service thread. */
static struct svc_channel local[SVC_MAX_CHANNELS];
/*