summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index c550843..7f3a4b2 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -624,6 +624,25 @@ struct svc_channel {
unsigned long gr_ram_userd_latch_at; /* jiffies at the latch */
bool gr_ram_userd_confirmed; /* +1/+2 step observed */
/*
+ * SESSION 153-CONT-5: rejected-latch memory. A speculative latch the
+ * pump rejects (frozen or jumped PUT) used to exhaust the RAM scan
+ * budget permanently: r936's kick channel latched a FROZEN lookalike
+ * (put=7 get=1 on a driver struct page), the pump rejected it twice,
+ * the 20-slice scan budget retired, and the channel went dark with no
+ * re-latch path - kick retires (and their publish writes) stopped for
+ * the rest of the session. Remember the rejected PA and its PUT: the
+ * scan skips that exact (pa, put) pair silently, re-adopts the block
+ * the moment its PUT moves (content change = new evidence), and each
+ * rejection re-arms the scan budget so one stale window can never kill
+ * the pipeline. The re-arm count is bounded (64: the r937 rate of
+ * ~4 rejections/min makes that >15 min of continuous retire activity
+ * on a client that only ever wrote one kick, while a truly dead
+ * channel still stops sweeping in bounded time).
+ */
+ u64 gr_ram_userd_reject_pa; /* PA of the rejected latch */
+ u32 gr_ram_userd_reject_put; /* its PUT at rejection time */
+ u8 gr_ram_userd_rejects; /* rejections seen (bound) */
+ /*
* SESSION 154 (M-GL1.2): content anchor for a client push whose
* translation went stale (r913: a validated pin kept answering for
* a reused page and the wrong-VAS walk answer was implausible while
@@ -18556,6 +18575,18 @@ static bool svc_gr_ram_userd_scan(struct nv_vgpu_device *vgpu,
continue;
}
/*
+ * SESSION 153-CONT-5: a previously rejected block at
+ * the same PUT is a frozen lookalike - do not spend a
+ * (re-armed) scan budget re-latching it, or the budget
+ * loops on the same stale window forever. A DIFFERENT
+ * PUT is content change (the block moved): adopt it
+ * again so a real control block that appears late is
+ * still picked up.
+ */
+ if ((gpa + o) == ch->gr_ram_userd_reject_pa &&
+ hp == ch->gr_ram_userd_reject_put)
+ continue;
+ /*
* SESSION 154 (M-GL1.2): a candidate that passed the
* shape gate, the entry validation, the page-density
* gate and the put cap is latched SPECULATIVELY. The
@@ -18607,6 +18638,12 @@ static bool svc_gr_ram_userd_scan(struct nv_vgpu_device *vgpu,
ch->gr_ram_userd_passes;
svc.chan[i].gr_ram_userd_logged =
ch->gr_ram_userd_logged;
+ svc.chan[i].gr_ram_userd_reject_pa =
+ ch->gr_ram_userd_reject_pa;
+ svc.chan[i].gr_ram_userd_reject_put =
+ ch->gr_ram_userd_reject_put;
+ svc.chan[i].gr_ram_userd_rejects =
+ ch->gr_ram_userd_rejects;
svc.chan[i].gr_ram_userd_watch_n =
ch->gr_ram_userd_watch_n;
for (wj = 0; wj < SVC_GR_USERD_WATCH; wj++) {
@@ -29523,6 +29560,24 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
ch->gr_ram_userd_latch_put,
put != ch->gr_ram_userd_latch_put ?
"" : " no advance in 15 s");
+ /*
+ * SESSION 153-CONT-5: one stale window must not
+ * kill the pipeline. Remember the rejected
+ * (pa, put) so the scan never re-latches the same
+ * frozen block, re-arm the scan budget (bounded)
+ * so a REAL control block that appears later can
+ * still be adopted, and only then drop the USERD.
+ * r936: the rejection retired the 20-slice budget
+ * and the kick channel never re-latched anything.
+ */
+ ch->gr_ram_userd_reject_pa = ch->userd_pa;
+ ch->gr_ram_userd_reject_put =
+ ch->gr_ram_userd_latch_put;
+ if (ch->gr_ram_userd_rejects < 64) {
+ ch->gr_ram_userd_rejects++;
+ ch->gr_ram_userd_passes = 0;
+ ch->gr_ram_userd_logged = false;
+ }
ch->userd_ok = false;
ch->userd_pa = 0;
ch->userd_as = 0;
@@ -29544,6 +29599,16 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc.chan[li].userd_ok = false;
svc.chan[li].userd_pa = 0;
svc.chan[li].userd_as = 0;
+ svc.chan[li].gr_ram_userd_passes =
+ ch->gr_ram_userd_passes;
+ svc.chan[li].gr_ram_userd_logged =
+ ch->gr_ram_userd_logged;
+ svc.chan[li].gr_ram_userd_reject_pa =
+ ch->gr_ram_userd_reject_pa;
+ svc.chan[li].gr_ram_userd_reject_put =
+ ch->gr_ram_userd_reject_put;
+ svc.chan[li].gr_ram_userd_rejects =
+ ch->gr_ram_userd_rejects;
break;
}
spin_unlock_irqrestore(&svc.chan_lock, lflags);
@@ -32221,6 +32286,13 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
ch->gr_ram_userd_latch_at;
svc.chan[k].gr_ram_userd_confirmed =
ch->gr_ram_userd_confirmed;
+ /* SESSION 153-CONT-5: rejected-latch memory. */
+ svc.chan[k].gr_ram_userd_reject_pa =
+ ch->gr_ram_userd_reject_pa;
+ svc.chan[k].gr_ram_userd_reject_put =
+ ch->gr_ram_userd_reject_put;
+ svc.chan[k].gr_ram_userd_rejects =
+ ch->gr_ram_userd_rejects;
svc.chan[k].gr_anchor_cursor = ch->gr_anchor_cursor;
svc.chan[k].gr_anchor_va = ch->gr_anchor_va;
svc.chan[k].gr_anchor_sweeps = ch->gr_anchor_sweeps;