diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 77a1fae..d69be19 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -573,6 +573,14 @@ struct sema_svc { u64 sem_write_reresolve; /* writes re-resolved after read-back */ u64 pool_alt_applied; /* pool releases fanned to a * displaced pin (ISSUE-0002) */ + u64 pool_residue; /* fresh-channel first releases whose + * pool word read far ahead of the + * payload (previous session's + * value in a reused pool page); + * re-seeded from the payload and + * applied instead of skipped as + * stale (ISSUE-0002 r63/r64) */ + u64 pool_residue_log; /* residue diagnostic budget */ u64 pushpg_fallback; /* injected pin rejected by content */ u64 gpfifo_skipped; /* stale entries consumed */ u64 gpfifo_rescued; /* unreadable push made readable @@ -3287,10 +3295,10 @@ static void svc_rebuild(struct nv_vgpu_device *vgpu) svc.releases_faked, svc.releases_recovered, svc.ops_once_skipped, svc.ops_reident, svc.opdef_held, svc.opdef_applied, svc.opdef_expired); - pr_info("sema-svc: counter pub_calls=%llu gr_rel=%llu reresolve=%llu pushpg_fb=%llu altw=%llu\n", + pr_info("sema-svc: counter pub_calls=%llu gr_rel=%llu reresolve=%llu pushpg_fb=%llu altw=%llu residue=%llu\n", svc.counter_pub_calls, svc.gr_rel_applied, svc.sem_write_reresolve, svc.pushpg_fallback, - svc.pool_alt_applied); + svc.pool_alt_applied, svc.pool_residue); if (svc.resc_run) pr_info("sema-svc: rescue_run=%llu (multi-page content pins)\n", svc.resc_run); @@ -6495,6 +6503,61 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, DMA_SEM_REDUCTION(dma) == SEM_REDUCTION_INC) ? 1 : 0); } else if (svc_pool_sem_va(sem_va) && + ch && ch->engine_type && + !ch->submissions && + cur > st.sem_payload) { + /* + * ISSUE-0002 (r63/r64): the + * first GPFIFO entry of a + * fresh CE channel carries + * the release that starts + * the channel's tracker. + * When the pool word + * already reads far ahead + * of the decoded payload + * through the injected pin, + * the word cannot be this + * session's live tracker + * (no entry of this channel + * has executed yet): it is + * the previous session's + * value in a reused pool + * page. svc_init_expected_ + * payload seeded the + * expectation from that + * residue, so the release + * was skipped as stale + * (payload <= cur) and the + * client's first tracker + * wait never completed + * (r64: cur=134, pay=1; + * r63: cur=114696). + * Re-seed the expectation + * from the payload and + * apply it absolute: for a + * monotonic tracker that is + * the exact value the + * client polls, and the + * fan-out/pending paths + * still own any displaced + * pin. + */ + ch->expected_sem_payload = + st.sem_payload; + ch->entry_want = st.sem_payload; + have_cur = true; + pending = 1; + svc.pool_residue++; + if (svc.pool_residue_log < 32) { + svc.pool_residue_log++; + pr_info("sema-chan: pool residue h=0x%x rank=%u va=0x%llx pay=%u cur=%u -> re-seed + apply (fresh channel)\n", + ch->h_object, + ch->ce_index, + sem_va, + st.sem_payload, + cur); + } + } else if (svc_pool_sem_va(sem_va) && (svc_pool_hold_active() || !cur)) { /* * A readable pool word of 0 |
