summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c96
1 files changed, 88 insertions, 8 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 6f4e387..9e0f3f4 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -27027,6 +27027,18 @@ static bool svc_ce_declared_userd(struct nv_vgpu_device *vgpu,
*/
static u32 svc_foreign_userd_skip_log;
+/*
+ * CONT.466 (wall (a) clause 1/2): bounded refusal witnesses for the
+ * DDX-family garbage class. c181 admitted a SYS block put=1 get=288190567
+ * (the entries>1024 exemption let get>put through) and the pump then
+ * CONFIRMED a block whose PUT jumped 1 -> 1170688059. The RAM scan, the FB
+ * shape scan and the pump's jump judge each log the first refusals so the
+ * next cycle's receipts name the gate that held.
+ */
+static u32 svc_userd_ddx_ramget_log;
+static u32 svc_userd_ddx_fbget_log;
+static u32 svc_userd_ddx_jump_log;
+
static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
u64 ring_pa, int ring_ap, u32 *put, u32 *get, int rrc)
{
@@ -27591,12 +27603,31 @@ ce_fb_scan:
* CE control pages also carry a GPU-owned GET,
* but bound it to one ring so a garbage pair
* (r1660: put=2880 get=188746560) cannot pass. */
- if (!hp || hp > ch->gpfifo_entries ||
- (hg > hp &&
- (ch->engine_type ?
- hg > hp + ch->gpfifo_entries :
- ch->gpfifo_entries <= 1024)))
+ if (!hp || hp > ch->gpfifo_entries)
+ continue;
+ /*
+ * CONT.466 (wall (a) clause 1): the DDX family
+ * must satisfy get <= put. The entries>1024
+ * exemption exists for large kernel rings whose
+ * GPU-owned GP_GET is uninitialised, but it also
+ * admitted garbage (c171: fb 0x960000 put=1
+ * get=917535) that the pump then confirmed.
+ */
+ if (hg > hp &&
+ (ch->engine_type ?
+ hg > hp + ch->gpfifo_entries :
+ (svc_userd_ddx_family(ch) ||
+ ch->gpfifo_entries <= 1024))) {
+ if (!ch->engine_type &&
+ svc_userd_ddx_family(ch) &&
+ svc_userd_ddx_fbget_log < 16) {
+ svc_userd_ddx_fbget_log++;
+ pr_info("sema-chan: userdp h=0x%x REFUSES fb 0x%llx put=%u get=%u (DDX get>put; c181 garbage class)\n",
+ ch->h_object, off, hp,
+ hg);
+ }
continue;
+ }
gate_n++;
/*
* CONT.438: the page-ownership gate. A block
@@ -31073,9 +31104,30 @@ static bool svc_gr_ram_userd_scan(struct nv_vgpu_device *vgpu,
* pump's confirm/reject) carry the ownership proof.
*/
if (!hp ||
- hp > (kick || entries > 1024 ? 0x100000 : 8) ||
- (hg > hp && entries <= 1024))
+ hp > (kick || entries > 1024 ? 0x100000 : 8))
continue;
+ /*
+ * CONT.466 (wall (a) clause 1): the DDX family must
+ * satisfy get <= put like every small ring. The
+ * entries>1024 exemption (large kernel rings with an
+ * uninitialised GPU-owned GP_GET) admitted garbage
+ * here (c181: pa=0x1020f8600 put=1 get=288190567 on
+ * entries=8192) which the pump then confirmed; the
+ * DDX tracker wait timed out and Xorg died on
+ * RM-local 0x51. The kick watch loop already refuses
+ * hg > hp, so this only aligns the content scan.
+ */
+ if (hg > hp &&
+ (entries <= 1024 || svc_userd_ddx_family(ch))) {
+ if (svc_userd_ddx_family(ch) &&
+ svc_userd_ddx_ramget_log < 16) {
+ svc_userd_ddx_ramget_log++;
+ pr_info("sema-chan: GR USERD h=0x%x rank=%u RAM scan REFUSES pa=0x%llx put=%u get=%u (DDX get>put; c181 garbage class)\n",
+ ch->h_object, ch->gr_index,
+ gpa + o, hp, hg);
+ }
+ continue;
+ }
{
u32 z = 0, zi;
@@ -44945,10 +44997,38 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
* h=0x1000013 legitimately wrapped 65536 -> 12 and
* the raw compare rejected the live block; see
* svc_userd_put_wrap().
+ *
+ * CONT.466 (wall (a) clause 2): a forward jump is
+ * progress only within half the ring. c181's garbage
+ * block read put=1 at adoption and put=1170688059 at
+ * the next pass; "any forward movement" confirmed it
+ * and the DDX tracker timed out on RM-local 0x51.
+ * Bound the raw step for the DDX family (the kick
+ * lane's free-running counter keeps the any-step
+ * rule): a jump past entries/2 is not a step, it
+ * falls through to the reprobe/defer/reject ladder
+ * so the scan re-adopts.
*/
stepped = wrap ?
(wstep && wstep <= ch->gpfifo_entries / 2) :
- put > ch->gr_ram_userd_latch_put;
+ (put > ch->gr_ram_userd_latch_put &&
+ (!(svc_userd_ddx_family(ch) && !kfam) ||
+ (ch->gpfifo_entries >= 2 &&
+ put - ch->gr_ram_userd_latch_put <=
+ ch->gpfifo_entries / 2)));
+ if (!stepped && !wrap && !kfam &&
+ svc_userd_ddx_family(ch) &&
+ ch->gpfifo_entries >= 2 &&
+ put > ch->gr_ram_userd_latch_put &&
+ put - ch->gr_ram_userd_latch_put >
+ ch->gpfifo_entries / 2 &&
+ svc_userd_ddx_jump_log < 16) {
+ svc_userd_ddx_jump_log++;
+ pr_info("sema-chan: GR USERD h=0x%x pa=0x%llx forward PUT jump REFUSED (put %u -> %u ent %u > half ring; c181 garbage class)\n",
+ ch->h_object, ch->userd_pa,
+ ch->gr_ram_userd_latch_put, put,
+ ch->gpfifo_entries);
+ }
if (stepped) {
ch->gr_ram_userd_confirmed = true;
ch->gr_ram_userd_defers = 0;