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