summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index a04a3c2..0c0e85b 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -2506,6 +2506,32 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
}
/*
+ * Apply the release BEFORE running the push's
+ * collected work. The client's tracker only
+ * observes the release, and its context-init
+ * deadline is what the whole run races against;
+ * running the memsets first added their full
+ * execution time to every push's visible
+ * completion latency. Ordering is still safe:
+ * this is the only writer of both the semaphore
+ * and the vidmem shadow, and the next push is
+ * not decoded until this call returns.
+ */
+ if (pending) {
+ svc.pushes_pending++;
+ if (DMA_SEM_REDUCTION_EN(dma) &&
+ DMA_SEM_REDUCTION(dma) ==
+ SEM_REDUCTION_INC)
+ cur += st.sem_payload;
+ else
+ cur = st.sem_payload;
+ if (!svc_sem_write(vgpu, sem_va, cur)) {
+ svc.releases_applied++;
+ svc.post_hint_until = jiffies + 10 * HZ;
+ }
+ }
+
+ /*
* The push's collected work always runs on real
* hardware; the release only orders observers.
* Execute it here, independently of whether the
@@ -2521,19 +2547,6 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
svc.ring_ops++;
ops_runs++;
}
- if (pending) {
- svc.pushes_pending++;
- if (DMA_SEM_REDUCTION_EN(dma) &&
- DMA_SEM_REDUCTION(dma) ==
- SEM_REDUCTION_INC)
- cur += st.sem_payload;
- else
- cur = st.sem_payload;
- if (!svc_sem_write(vgpu, sem_va, cur)) {
- svc.releases_applied++;
- svc.post_hint_until = jiffies + 10 * HZ;
- }
- }
/*
* Exact-slot fallback: the releasing channel's