diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 96 |
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; |
