diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-11 18:04:18 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-11 18:04:18 -0500 |
| commit | a4013c7e2fc091bc2755ea0860e16ee511beb70f (patch) | |
| tree | ff7540dbb15921e93c86e08baf2fb079b722d893 /kernel/gsp_sema_service.c | |
| parent | afc9afdb63ba1798b91e0be499291c9a6670a9dc (diff) | |
| download | open-iov-a4013c7e2fc091bc2755ea0860e16ee511beb70f.tar.gz open-iov-a4013c7e2fc091bc2755ea0860e16ee511beb70f.zip | |
vgsp: periodic GLX shared-surface refCount watchdog
The GLX client writes lastKickoffRefCount during init before its first kick,
while the X DDX may already poll gpuRefCount against it; if a previous client
left the count lower the wait can only clear after the GLX request the DDX is
blocking. Once per second (and on a manual sema_gl_shsurf_kick write) walk the
known shared-surface VA and the last decoded release VA, and author the
client's plausible lastKickoffRefCount forward-only. The strict lkr gate
(high dword zero, small, cur < lkr) keeps it a no-op when the VA maps
something else. Gated by sema_gl_shsurf_watch (default on).
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 44 |
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]; /* |
