summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_rm_emulation.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
-rw-r--r--kernel/gsp_rm_emulation.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index ceb3314..d43333f 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -566,8 +566,22 @@ static int gsp_rm_send_flags(struct gsp_emu_context *ctx, u32 function,
u32 peer_read = 0;
bool have_peer = false;
int w;
+ int wait_iters = 50;
- for (w = 0; w < 51; w++) {
+ /*
+ * r1615: critical event wake-ups (channel completions, and in
+ * particular the display/mode-set completion the X server's
+ * 2D sync waits for) must not be dropped just because the
+ * guest is briefly behind. Pump the consumption cursor for up
+ * to 200 ms so the guest's RM thread can drain; only drop if
+ * the ring is still full after that (the 0.5 s hint re-post
+ * retries). Non-critical event wake-ups keep the old
+ * drop-immediately policy; replies keep their 50 ms wait.
+ */
+ if (function == GSPRM_RPC_EVENT_POST_EVENT)
+ wait_iters = critical ? 200 : 0;
+
+ for (w = 0; w <= wait_iters; w++) {
u32 used, space, rxoff = 0;
u8 shdr[32];
@@ -617,7 +631,7 @@ static int gsp_rm_send_flags(struct gsp_emu_context *ctx, u32 function,
* two fn=0x1 replies dropped at boot -> the device
* never comes up).
*/
- if (function == GSPRM_RPC_EVENT_POST_EVENT || w == 50)
+ if (w == wait_iters)
break;
mutex_unlock(&rm->stat_lock);
msleep(1);