summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 04bffc5..75c7645 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -14142,6 +14142,8 @@ static bool svc_gr_ram_ring_scan(struct nv_vgpu_device *vgpu,
u64 start = ch->gr_ram_cursor;
u64 end = start + SVC_GR_RAM_SLICE;
u64 gpa;
+ int i;
+ unsigned long flags;
if (end > SEMA_PA_MAX)
end = SEMA_PA_MAX;
@@ -14198,6 +14200,23 @@ static bool svc_gr_ram_ring_scan(struct nv_vgpu_device *vgpu,
ch->h_object, ch->gr_index, ch->gr_ram_passes,
ch->gpfifo_va);
}
+ /*
+ * Persist the cursor immediately: the pump's stalled-userd path
+ * `continue`s past the end-of-pass write-back, so without this the
+ * scan would restart from slice 0 every pass and never reach the
+ * ring's page.
+ */
+ spin_lock_irqsave(&svc.chan_lock, flags);
+ for (i = 0; i < SVC_MAX_CHANNELS; i++) {
+ if (svc.chan[i].valid && svc.chan[i].vgpu == vgpu &&
+ svc.chan[i].h_object == ch->h_object) {
+ svc.chan[i].gr_ram_cursor = ch->gr_ram_cursor;
+ svc.chan[i].gr_ram_passes = ch->gr_ram_passes;
+ svc.chan[i].gr_ram_logged = ch->gr_ram_logged;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&svc.chan_lock, flags);
return false;
}