diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-09 14:50:03 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-09 14:50:03 -0500 |
| commit | ad93b227526f42fa4ea7e529de883a9fa600c34d (patch) | |
| tree | 8b76a1a3993c289e5e380e1c548a505db32e0292 /kernel/gsp_rm_emulation.c | |
| parent | 3701f985edb89224f6a5c1237b21ddb8e527e126 (diff) | |
| download | open-iov-ad93b227526f42fa4ea7e529de883a9fa600c34d.tar.gz open-iov-ad93b227526f42fa4ea7e529de883a9fa600c34d.zip | |
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.
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 11 |
1 files changed, 11 insertions, 0 deletions
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); } |
