summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-18 15:40:56 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-18 15:41:56 -0400
commitfb3db6dfc686405fc9fb37ecdf99e3b2ba138d6e (patch)
tree3351dd2ff509aac17d3ea2cc1781275a22804930 /kernel
parent97f3973aa310c3f3387c4e69c274c5075f2f779e (diff)
downloadopen-iov-fb3db6dfc686405fc9fb37ecdf99e3b2ba138d6e.tar.gz
open-iov-fb3db6dfc686405fc9fb37ecdf99e3b2ba138d6e.zip
vgsp: fail4 r233 - budgeted REC-DUMP + READ-DIVERGE-WIT (fill vs copy-path vs ledger)
r231/r232: the probe-class launches produced zero REC-DUMP lines while the transformer's 8+2 appeared - the per-line pr_info_ratelimited was suppressed wholesale during the probe's post-stall logging burst. REC-DUMP now uses plain pr_info under a boot-wide 512-line budget, so a <=64-rec launch always dumps its full rec table. READ-DIVERGE-WIT (sema service, rec-build loop): for small launches the three resolutions of each VA are compared side by side - the fill's dg->pa (the page whose content the copy-in stages; exactly what the engine reads), svc_op_translate (the H2D/D2H copy path's resolver) and the ledger's write landing. A page-level split is logged with op_src/op_rc and an op-miss token. Bounded: first 8 recs, boot budget 128. Static permutation check (negative): reloc_va is assigned sequentially in fill order (svc_gr_data_fill), copy-in/out iterate recs in order, the engine reads reloc-base + linear offset, and the per-page copy loop folds in-page offsets correctly on every resolver path; no sort/rotate/LIFO order found in the page-table or copy paths. The remaining split suspect is the m171/m180 ledger DIVERGE preference - exactly what READ-DIVERGE-WIT compares. Build green. (cherry picked from commit 59e50207d60067b5d1e3a0546f20e9b22c92e112)
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c18
-rw-r--r--kernel/gsp_sema_service.c36
2 files changed, 49 insertions, 5 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 7b6a1bf..430b518 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -165,6 +165,7 @@ static u64 gsp_phys_gr_outwit_va[GSP_PHYS_GR_OUTWIT_SLOTS];
static u32 gsp_phys_gr_outwit_bi[GSP_PHYS_GR_OUTWIT_SLOTS];
static u32 gsp_phys_gr_outwit_n;
static u32 gsp_phys_gr_alias_log; /* boot-wide alias-line budget */
+static u32 gsp_phys_gr_recdump_budget; /* r233 REC-DUMP boot budget */
bool gsp_phys_boot_enabled(void)
{
@@ -18733,18 +18734,25 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
* HPAs against the buffer the client actually uploaded (distinct
* VAs collapsing onto one HPA, or HPAs in a foreign range, are
* visible directly). Big launches log the first/last 8 recs only.
+ * r233: plain pr_info with a boot-wide line budget - the earlier
+ * pr_info_ratelimited version was suppressed wholesale during the
+ * probe's post-stall logging burst, so the probe-class recs never
+ * reached the ring.
*/
- if (gsp_phys_gr_copywit_enabled() && req->n_data) {
+ if (gsp_phys_gr_copywit_enabled() && req->n_data &&
+ gsp_phys_gr_recdump_budget < 512u) {
u32 d;
for (d = 0; d < req->n_data; d++) {
if (req->n_data > 64u && d >= 8u &&
d < req->n_data - 8u)
continue;
- pr_info_ratelimited("vgsp-gr: REC-DUMP[%u/%u] va=0x%llx hpa=0x%llx reloc=0x%llx\n",
- d, req->n_data, req->data[d].va,
- req->data[d].hpa,
- req->data[d].reloc_va);
+ if (gsp_phys_gr_recdump_budget >= 512u)
+ break;
+ gsp_phys_gr_recdump_budget++;
+ pr_info("vgsp-gr: REC-DUMP[%u/%u] va=0x%llx hpa=0x%llx reloc=0x%llx\n",
+ d, req->n_data, req->data[d].va,
+ req->data[d].hpa, req->data[d].reloc_va);
}
}
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 02c100f..d9f5895 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -12666,6 +12666,7 @@ static unsigned long svc_fwd_state;
static u64 svc_fwd_requests;
static u64 svc_fwd_dropped;
static u32 svc_grvaudit_launches; /* GRVAUDIT: per-launch audit counter */
+static u32 svc_readdiv_log; /* r233 READ-DIVERGE-WIT budget */
/*
* Pause gate shared by the pump's request path and the backend release path:
* quiesce takes this lock, sets paused and waits for the in-flight work item;
@@ -14388,6 +14389,41 @@ static void svc_fwd_gr_work(void)
}
}
/*
+ * r233 READ-DIVERGE-WIT: the engine's read of this VA uses
+ * exactly what the fill resolved (dg->pa: the page whose
+ * content was copied into the bounce). The copy paths (H2D
+ * writes, D2H reads) resolve independently through
+ * svc_op_translate/ledger. For small launches (the probe
+ * class) compare the three for the first recs and flag any
+ * page-level split - the direct witness for a read/write
+ * permutation. Bounded: first 8 recs, 4 lines per launch,
+ * boot budget 128.
+ */
+ if (svc_fwd_req.gr_n_data <= 64u && i < 8u &&
+ svc_readdiv_log < 128u) {
+ u64 opa = 0, lpa2 = 0;
+ u32 oap = 0, lap2 = 0;
+ bool op_miss, have_led;
+
+ op_miss = svc_op_translate(svc_fwd_req.vgpu, dg->va,
+ &opa, &oap) != 0;
+ have_led = !svc_ledger_lookup(dg->va, &lpa2, &lap2);
+ if (op_miss || (!op_miss &&
+ (opa & ~(u64)(SEMA_PAGE_SIZE - 1)) !=
+ (dg->pa & ~(u64)(SEMA_PAGE_SIZE - 1))) ||
+ (have_led &&
+ (lpa2 & ~(u64)(SEMA_PAGE_SIZE - 1)) !=
+ (dg->pa & ~(u64)(SEMA_PAGE_SIZE - 1)))) {
+ svc_readdiv_log++;
+ pr_info("vgsp-gr: READ-DIVERGE-WIT va=0x%llx fill_pa=0x%llx op_pa=0x%llx op_src=%u op_rc=%d ledger_pa=0x%llx%s\n",
+ dg->va, dg->pa, opa,
+ op_miss ? 0xffffffffu : svc.op_tr_src,
+ op_miss ? -ENOENT : 0,
+ have_led ? lpa2 : 0,
+ op_miss ? " (op-miss)" : "");
+ }
+ }
+ /*
* C3 (data class): after the run the backend copies this
* page's results back to dg->pa (gsp_phys_booter.c copy-out).
* Record that page as the truth for this VA so the guest's