diff options
| -rw-r--r-- | kernel/gsp_sema_service.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 8e6401d..7bd1b26 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -47161,7 +47161,13 @@ static void svc_scrub_one(struct nv_vgpu_device *vgpu, struct svc_scrub *s) s->put_last = put; s->consumed = put ? put - 1 : s->entries - 1; } else if (s->submitted == s->authored && - s->authored_gen == s->pa_gen) { + s->authored_gen == s->pa_gen && + !(s->registered && !s->submitted)) { + /* + * CONT.414: re-author the release pair every pass while a + * scanner-registered buffer has no observed submissions, so a + * guest rewrite of the polled word cannot re-block the wait. + */ return; /* nothing new; no guest writes */ } @@ -47181,15 +47187,28 @@ static void svc_scrub_one(struct nv_vgpu_device *vgpu, struct svc_scrub *s) */ svc_write_ap(vgpu, s->userd_pa + SVC_USERD_GP_GET, s->userd_as, &put, sizeof(put)); + /* + * CONT.414: a scanner-registered channel buffer with no observed + * USERD GP_PUT submissions is the X DDX's vidheap scrub wait: the + * guest RM polls the finish payload at channel buffer + 0x6c004 + * (channelWaitForFinishPayload) while the host still reads GP_PUT=0, + * so the put-based forward authoring would write sema=entries-1 and + * fin=0 - the exact values that leave channelWaitForFreeEntry and + * channelWaitForFinishPayload blocked (r1729: Xorg holds the NVRM + * RM API write lock in that wait, glxgears and nvidia-modeset D on + * os_acquire_rwlock_write). Author the proven all-ones release pair + * (CONT.408/409) until a real put advance gives us progress to + * mirror; 0xffffffff can never equal a putIndex below the ring size + * and the folded finish counter is at its maximum. + */ { - u32 sema = s->consumed; + bool release = s->registered && !s->submitted; + u32 idle = 0xffffffffu; + u32 sema = release ? idle : s->consumed; + u32 fin = release ? idle : (u32)s->submitted; svc_write_ap(vgpu, s->hsem_pa, SVC_APERTURE_SYS, &sema, sizeof(sema)); - } - { - u32 fin = (u32)s->submitted; - svc_write_ap(vgpu, s->fin_pa, SVC_APERTURE_SYS, &fin, sizeof(fin)); } |
