summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 02:52:11 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 02:52:11 -0500
commit579e29b6e5924873489e88afa7796a2bda3e95a2 (patch)
tree63b393e4517dcede93a3b10f9f853b2c2b8a9d6d
parent78225d9c81f22dbcd5af92aa088e4eeabe91e200 (diff)
downloadopen-iov-579e29b6e5924873489e88afa7796a2bda3e95a2.tar.gz
open-iov-579e29b6e5924873489e88afa7796a2bda3e95a2.zip
vgsp: serve word-34..47 section pages from their resolved PAs; seed the pointer pairs (n_data 0->1024)
The final-pixel-wall data window: svc_gr_data_fill discarded a candidate page that HAD resolved in gr_pages (launch_internal blanket skip: c203 evidence 'page[2] va=0x120400000 pa=0xa00000 ap=2 word=34' + '10 candidate ptrs, 0 pages resolved; 7 dropped' -> GR-DEC n_data=0), and the stream3d lane (qmd=0x0) never seeded the capture's decoded operand pairs (inline-QMD words 34..47) as candidates. Serve word-34..47 pages from their resolved gr_pages PA (li_pa, span=1; word 32/48/49 stay excluded as before) and seed the pointer pairs from a request-carried copy (race-free vs the capture ring). Live proof c215: 'li cand va=0x120400000 word=34 pa=0xa00000 ap=2' -> 'GR-DEC n_data=1024' (was 0). Residual: the 1524 B first-frame's pointer pages are not yet resolvable at that instant (n_ptr_req=5 seed_add=0; frames 2+ resolve 1024) - resolver timing, documented. Also documented (no change): the copy-out refusal for dst=0x120700000 (the GL client's fixed-CB page) falls through to the forced-seed path and is benign for pixels; the TRUE px0 blocker is engine-zero-write: every stream3d launch ends 'NOWRITE-CONFIRMED ... n_data=1024 tracked=1024 wrote=0' + 'NOWRITE-REGS fe_esr=0x80000000 trap=0x8000022c/00000800/00000000' even with the full RT window (SURF-PRELUDE target=0xa000000) - the engine executes but stores nothing.
-rw-r--r--kernel/gsp_sema_service.c112
1 files changed, 107 insertions, 5 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 34e2b49..6ce84f1 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -34942,6 +34942,14 @@ struct svc_fwd_req {
u32 gr_n_prog_binds;
u64 gr_prog_bind_va[SVC_GR_CAND_PROG_BINDS];
u32 gr_prog_bind_slot[SVC_GR_CAND_PROG_BINDS];
+ /*
+ * ENG10: the capture's decoded operand pointer pairs (inline-QMD words
+ * 34..47). Carried on the request like gr_prog_bind_va so the fill's
+ * candidate seed reads the REQUEST's capture, not whatever the
+ * rotating svc_gr_cand ring holds when the work item runs.
+ */
+ u32 gr_n_pointer;
+ u64 gr_pointer_va[SVC_GR_POINTER_MAX];
u64 gr_param_va;
u32 gr_param_size;
u32 gr_qmd[SVC_GR_QMD_WORDS];
@@ -39512,6 +39520,8 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
static u64 svc_gr_reloc_half_key;
static u8 svc_gr_reloc_half;
u64 reloc_off = 0;
+ u32 eng10_seed_added = 0;
+ static u32 eng10_li_log;
if (region_on) {
if (svc_gr_cand.push_va != svc_gr_reloc_half_key) {
@@ -39883,11 +39893,45 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
}
}
}
+ /*
+ * ENG10 (r1780 GL): the stream3d sections carry no QMD page (qmd=0),
+ * so the qmd-ptr seed above has no words to work from and the only
+ * candidates left were the param-page content scans - junk VAs whose
+ * pages resolve to nothing (c203/c211: 24 cands, 0 resolved,
+ * GR-DEC n_data=0 on every first-frame 1524 B launch while the
+ * launch's own word-34..47 pages sat RESOLVED in gr_pages:
+ * ptr[0] 0x120400000 -> pa=0xa00000/vidmem). The capture DID decode
+ * those operand pointer pairs (svc_gr_cand.pointer_va[] = the
+ * inline-QMD words 34..47); seed them as candidates here - exactly
+ * what the qmd-ptr seed does when a QMD exists. The span resolution
+ * then serves each from its gr_pages pa (the li_pa clause below).
+ * is_arg stays false so the m170 fail-closed hold semantics are
+ * unchanged (these are operands, not the argument set).
+ */
+ for (i = 0; i < svc_fwd_req.gr_n_pointer; i++) {
+ u64 pv = svc_fwd_req.gr_pointer_va[i];
+ u64 pw;
+
+ if (pv < 0x10000000ULL || pv >= (1ULL << 47) || (pv & 3))
+ continue;
+ pw = pv & ~(u64)(SEMA_PAGE_SIZE - 1);
+ for (w = 0; w < n_cand; w++)
+ if (wins[w] == pw)
+ break;
+ if (w == n_cand && n_cand < ARRAY_SIZE(wins)) {
+ wins[n_cand++] = pw;
+ eng10_seed_added++;
+ }
+ }
if (gsp_sema_dbg && svc_gr_pages_log < 48) {
svc_gr_pages_log++;
- pr_info("sema-gr: fill cand n=%u pages=%u push=0x%llx\n",
+ pr_info("sema-gr: fill cand n=%u pages=%u push=0x%llx n_ptr_req=%u ptr0=0x%llx seed_add=%u\n",
n_cand, svc_fwd_req.gr_n_pages,
- svc_fwd_req.gr_push_va);
+ svc_fwd_req.gr_push_va,
+ svc_fwd_req.gr_n_pointer,
+ svc_fwd_req.gr_n_pointer ?
+ svc_fwd_req.gr_pointer_va[0] : 0ull,
+ eng10_seed_added);
for (w = 0; w < n_cand && w < 12; w++)
pr_info("sema-gr: win[%u] va=0x%llx arg=%u\n",
w, wins[w], is_arg[w]);
@@ -39976,6 +40020,9 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
(base & ~(u64)(SEMA_PAGE_SIZE - 1)) ==
(svc_fwd_req.gr_param_va & ~(u64)(SEMA_PAGE_SIZE - 1)))
continue;
+ u64 li_pa = 0;
+ u32 li_ap = 0;
+
{
bool launch_internal = false;
@@ -39988,10 +40035,47 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
(base & ~(u64)(SEMA_PAGE_SIZE - 1)) ==
(pp->va & ~(u64)(SEMA_PAGE_SIZE - 1))) {
launch_internal = true;
+ /*
+ * ENG10 (r1780 GL, c203 evidence): the
+ * capture can ALREADY have resolved a
+ * pointer-pair page: the 288 B section's
+ * word-34 operand 0x120400000 sat in
+ * gr_pages as pa=0xa00000/vidmem while
+ * this blanket skip kept it out of the
+ * data window - the whole candidate set
+ * then resolved 0 pages and GR-DEC
+ * stayed n_data=0 ("fill: 0 pages
+ * resolved; 7 dropped"). Serve the
+ * resolved pointer-pair page (words
+ * 34..47 are the launch's device
+ * operands) from gr_pages below.
+ * Word 32 (param) and 48/49 (program)
+ * remain excluded: their shadow/Tier-2
+ * paths own them and must not be
+ * re-relocated as data.
+ */
+ if (pp->qmd_word >= 34u &&
+ pp->qmd_word <= 47u && pp->pa) {
+ li_pa = pp->pa;
+ li_ap = pp->ap;
+ if (eng10_li_log < 32) {
+ eng10_li_log++;
+ pr_info("sema-gr: li cand va=0x%llx word=%u pa=0x%llx ap=%u\n",
+ base,
+ pp->qmd_word,
+ pp->pa,
+ pp->ap);
+ }
+ } else if (eng10_li_log < 32) {
+ eng10_li_log++;
+ pr_info("sema-gr: li cand va=0x%llx word=%u pa=0x%llx (NOT served: word/pa)\n",
+ base, pp->qmd_word,
+ pp->pa);
+ }
break;
}
}
- if (launch_internal)
+ if (launch_internal && !li_pa)
continue;
}
span = (base >= 0x40000000000ULL) ? per_ptr : 1u;
@@ -40064,7 +40148,18 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
u64 vpa = 0;
int vap = SVC_APERTURE_SYS;
- if (surf_vas_h &&
+ /*
+ * ENG10: a pointer-pair page the capture already
+ * resolved (gr_pages pa/ap) is the strongest
+ * source - the same pages the launch's Tier-2
+ * shadow path uses. Served span=1 (low VA rule).
+ */
+ if (li_pa &&
+ va == (base & ~(u64)(SEMA_PAGE_SIZE - 1))) {
+ pa = li_pa;
+ ap = li_ap;
+ cand_anchored = true;
+ } else if (surf_vas_h &&
!svc_vas_lookup_h(vgpu, surf_vas_h, va,
&vpa, &vap)) {
static u32 surf_vas_log;
@@ -40661,7 +40756,7 @@ static void svc_gr_inline_retarget(u64 prog_va, const u64 *binds, u32 n_binds)
static int svc_gr_req_fill(struct nv_vgpu_device *vgpu,
const struct svc_channel *ch)
{
- u32 i;
+ u32 i, pb2;
svc_fwd_req.done = false;
svc_fwd_req.hw_rc = 0;
@@ -40701,6 +40796,13 @@ static int svc_gr_req_fill(struct nv_vgpu_device *vgpu,
svc_gr_cand.prog_bind_slot[pb];
}
}
+ /* ENG10: snapshot the decoded operand pointer pairs (words 34..47) so
+ * the fill's seed loop cannot race the rotating capture ring. */
+ svc_fwd_req.gr_n_pointer = svc_gr_cand.n_pointer;
+ if (svc_fwd_req.gr_n_pointer > SVC_GR_POINTER_MAX)
+ svc_fwd_req.gr_n_pointer = SVC_GR_POINTER_MAX;
+ for (pb2 = 0; pb2 < svc_fwd_req.gr_n_pointer; pb2++)
+ svc_fwd_req.gr_pointer_va[pb2] = svc_gr_cand.pointer_va[pb2];
memcpy(svc_fwd_req.gr_raw, svc_gr_cand.raw,
sizeof(svc_fwd_req.gr_raw));
svc_fwd_req.gr_qmd_dev_va = svc_gr_cand.qmd_dev_va;