diff options
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 10d6b80..b66cfd7 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -190,6 +190,15 @@ struct sema_svc { u64 last_build; u64 last_scan; + /* + * Completion hint window: after a channel completes work the client is + * waiting on, keep re-posting the event for a few seconds. A client + * that starts waiting after the completion would otherwise lose the + * (edge-triggered) wake-up. + */ + u64 post_hint_until; + u64 last_hint; + /* registered guest channels (GPFIFO-driven push execution) */ spinlock_t chan_lock; struct svc_channel chan[SVC_MAX_CHANNELS]; @@ -1642,6 +1651,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, cur + payload : payload; if (!svc_sem_write(vgpu, va, cur)) svc.releases_applied++; + svc.post_hint_until = jiffies + 10 * HZ; } } off += 4 + count * 4; @@ -1701,6 +1711,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (!svc_sem_write(vgpu, va, st.rs_payload)) svc.releases_applied++; + svc.post_hint_until = jiffies + 10 * HZ; break; } default: @@ -1825,6 +1836,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, cur = st.sem_payload; if (!svc_sem_write(vgpu, sem_va, cur)) svc.releases_applied++; + svc.post_hint_until = jiffies + 10 * HZ; } /* release ends the push */ n_ops = 0; @@ -1928,6 +1940,7 @@ static u32 svc_apply_page_data(struct nv_vgpu_device *vgpu, const u8 *buf, if (svc_sem_write(vgpu, va, payload) == 0) { svc.releases_applied++; + svc.post_hint_until = jiffies + 10 * HZ; applied++; if (payload != cur + 1) { svc.releases_jumped++; @@ -2212,6 +2225,10 @@ static void svc_notify_complete(struct nv_vgpu_device *vgpu, * thread waits on (a real GPU would raise an interrupt here). */ gsp_rm_post_channel_event(vgpu, ch->h_object); + + /* Keep the completion visible to clients that start waiting + * after the event fired. */ + svc.post_hint_until = jiffies + 10 * HZ; } } @@ -2526,6 +2543,21 @@ static int svc_thread(void *arg) svc_pump_channels(vgpu); /* + * Completion hint: re-post the events for a few seconds after a + * completion, so a client that starts waiting after the + * edge-triggered wake-up still observes it. + */ + if (time_before(jiffies, (unsigned long)svc.post_hint_until) && + time_after(jiffies, (unsigned long)svc.last_hint + HZ / 2)) { + int rc; + + svc.last_hint = jiffies; + rc = gsp_rm_post_all_events(vgpu); + pr_info_ratelimited("sema-svc: completion hint rc=%d\n", + rc); + } + + /* * Fast path for the pushes themselves: every mapped page is a * candidate pushbuffer page, and there are far fewer of those * than there are pages of guest RAM. |
