From ad93b227526f42fa4ea7e529de883a9fa600c34d Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 9 Nov 2026 14:50:03 -0500 Subject: vgsp-sema: keep the scrubber release alive while the event pump blocks The guest's PMA scrub wait and the host's status-queue pump can deadlock: the X server's scrub wait holds the guest RM lock the status consumer needs, the ring fills, and every critical event post then waits out its full 200 ms ring-full budget. A service pass can take many seconds, so the next pass's scrub step - the only thing that can release the scrub wait - is starved and the guest never makes progress. Run the scrub step from inside the send path's ring-full wait (service thread only), and re-resolve the scrubber's finish/host-sema words on every pass instead of once: the guest re-creates its RM kernel VAS and re-maps the channel buffer under the same GPU VA (observed: gpfifo VA 0x120064000 moved from PA 0x127e6a000 to 0x1122e9000), so a once-only resolution authored a page the guest no longer polled. Prefer the RM kernel VAS (h=0xc) RAM mapping over a client VAS vidmem mapping, and force re-resolution when a scrubber re-registers. --- kernel/gsp_rm_emulation.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'kernel/gsp_rm_emulation.c') diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 37b2200..c14a767 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -639,6 +639,17 @@ static int gsp_rm_send_flags(struct gsp_emu_context *ctx, u32 function, if (w == wait_iters) break; mutex_unlock(&rm->stat_lock); + /* + * r1668: a full status ring means the guest's RM + * consumer is blocked, and the usual cause is the + * CeUtils scrub wait holding the RM lock the event + * callback needs. Authoring the scrubber's finish + * payload is the only way out, but the pump cannot + * reach its next pass while this post waits, so run + * the scrub step here (service thread only; no-op + * elsewhere). + */ + gsp_sema_service_scrub_pump(ctx->vgpu); msleep(1); mutex_lock(&rm->stat_lock); } -- cgit v1.2.3