diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 18:40:12 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 18:40:12 -0400 |
| commit | 41f6bf1a07fbf33036d31fe64c98d64cfe621e67 (patch) | |
| tree | d748c222cb7170ef165f100cb9658b1b8e78f8a2 /kernel/gsp_sema_service.c | |
| parent | 4f28cbed07a20b290891e7325a07072326c78167 (diff) | |
| download | open-iov-41f6bf1a07fbf33036d31fe64c98d64cfe621e67.tar.gz open-iov-41f6bf1a07fbf33036d31fe64c98d64cfe621e67.zip | |
r576 diag: launch-decision + event-post payload witnesses (gsp_phys_gr_dec_log, gsp_rm_ev_log)
The GR launch-decision dump logs, for the first N draws whose fill saw
dropped pages / a partial argument set or whose decision point carries a
dstpend/copy-pending verdict: the decision verdicts, the launch's resolved
data pages (VA -> guest PA), the live deferred-write records and the pending
CE opdef entries - the operand evidence needed to explain a red draw of the
readback lottery (the wrong-but-similar page hypothesis).
The event-post witness logs every EVENT_POST_EVENT record actually sent with
its full payload (hClient/hEvent/notifyIndex/data) and send result, plus a
sentinel when post_all_events found valid events but posted none while none
were dedup-skipped. This is the evidence needed when a client parks waiting
for a completion wake-up that never arrives (the 2nd-client device-state
spin): it shows whether the post was generated, for whom, and whether the
status-queue write accepted it or dropped it (burst cap / ring full).
Both are inert by default (budget 0).
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index fbc0772..dfe7c3f 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -20986,6 +20986,65 @@ static bool svc_copy_pending(void) return pending; } +/* + * r576 DIAG: the GR launch-decision witness (gsp_phys_gr_dec_log=N budget + * per boot). Logged from svc_gr_request right after the fill, for launches + * whose fill saw dropped pages / a partial argument set or whose decision + * point carries a dstpend/copy-pending verdict - i.e. exactly the draws the + * r566/r567/r568 guards can defer or (on their blind spots) forward. The + * data-page list is the operand evidence: each VA -> guest PA the engine + * will read; a wrong-but-valid PA here (vs the page the client's H2D wrote + * for the same VA) is the failure mechanism the readback lottery draws. + */ +unsigned gsp_phys_gr_dec_log_max; +static unsigned svc_gr_dec_log; + +static void svc_gr_dec_dump(const struct svc_channel *ch) +{ + bool dstpend, copypend; + u32 i, n = 0; + + if (svc_gr_dec_log >= gsp_phys_gr_dec_log_max) + return; + svc_gr_dec_log++; + + dstpend = svc_gr_dstpend_overlap(); + copypend = svc_copy_pending(); + + pr_info("vgsp-gr: GR-DEC h=0x%x push=0x%llx n_data=%u dropped=%u partial=%d stalled=%d dstpend=%d copypend=%d defer_exp=%d\n", + ch->h_object, svc_gr_cand.push_va, svc_fwd_req.gr_n_data, + svc_fwd_req.gr_dropped, + svc_fwd_req.gr_arg_partial ? 1 : 0, + svc_gr_data_stalled ? 1 : 0, + dstpend ? 1 : 0, copypend ? 1 : 0, + svc_gr_defer_expired(svc_gr_cand.push_va) ? 1 : 0); + + for (i = 0; i < svc_fwd_req.gr_n_data && i < 32; i++) + pr_info("vgsp-gr: GR-DEC data[%u] va=0x%llx pa=0x%llx ap=%u reloc=0x%llx\n", + i, svc_fwd_req.gr_data[i].va, + svc_fwd_req.gr_data[i].pa, svc_fwd_req.gr_data[i].ap, + svc_fwd_req.gr_data[i].reloc_va); + + for (i = 0, n = 0; i < svc_dstpend_n && n < 16; i++) { + if (!svc_dstpend[i].va_page) + continue; + n++; + pr_info("vgsp-gr: GR-DEC dstpend va=0x%llx age_ms=%u\n", + svc_dstpend[i].va_page, + jiffies_to_msecs(jiffies - svc_dstpend[i].since)); + } + + for (i = 0, n = 0; i < SVC_OPDEF_SLOTS && n < 8; i++) { + if (!svc_opdef[i].active || !svc_opdef[i].n) + continue; + n++; + pr_info("vgsp-gr: GR-DEC opdef h=0x%x entry=%u n=%u age_ms=%u\n", + svc_opdef[i].h_object, svc_opdef[i].entry_idx, + svc_opdef[i].n, + jiffies_to_msecs(jiffies - svc_opdef[i].since)); + } +} + static bool svc_gr_request(struct nv_vgpu_device *vgpu, const struct svc_channel *ch) { @@ -21084,6 +21143,15 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu, return false; } /* + * r576 DIAG: witness the decision inputs of the draws the guards + * care about (see svc_gr_dec_dump). + */ + if (gsp_phys_gr_dec_log_max && + (svc_fwd_req.gr_dropped > 0 || svc_fwd_req.gr_arg_partial || + svc_gr_data_stalled || svc_gr_dstpend_overlap() || + svc_copy_pending())) + svc_gr_dec_dump(ch); + /* * r541: launch-ordering guard. The fill's data pages are what the * engine will read; if any of them is the target of a device copy * that decoded but has NOT executed yet (svc_dstpend_note - the |
