diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-31 02:34:15 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-31 02:34:15 -0400 |
| commit | 667491fe59737ebfb327804d361b2eb0a8b170bb (patch) | |
| tree | c265755724f5f61449da84f3779c4d182a2fd025 | |
| parent | 5620ed076c87be100be87432c6d5b3035a46ed6f (diff) | |
| download | open-iov-667491fe59737ebfb327804d361b2eb0a8b170bb.tar.gz open-iov-667491fe59737ebfb327804d361b2eb0a8b170bb.zip | |
vgsp+diag: debugfs sema_setup_demand (armed setup-hold VA set, 0444 seq_file) + pin_gr_stream demand loop reads it (kills dmesg-ring race; 20s resend/300s expiry), bounded 3D raw dump of pre-drop window - MME-PRELUDE emitted gen=2 words=512 (context alive submissions=760); NEW WALL: first beef window loads context + clean MME (mme_esr=80000000) then Class Error ChId 0001 Class 0xc597 Offset 0x1168 (SET_VERTEX_ATTRIBUTE_A(2)) ErrorCode 0x5 + poison; emitted attr runs byte-faithful; next: attr/pipeline prelude (0x1100-0x1200/0x2000-0x2060) + gate first launch on mature prelude - SESSION 153 r1091-r1094
| -rw-r--r-- | kernel/gsp_phys_booter.c | 40 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.c | 129 | ||||
| -rw-r--r-- | tools/guest-diag/pin_gr_stream.py | 18 |
3 files changed, 186 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index bb75a8c..3bbcf45 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -21878,6 +21878,46 @@ gr_page_unmapped: } } /* + * SESSION 153-CONTINUED-56: bounded RAW (pre-drop, pre-reloc) + * window dump so the emitted window can be diffed against the + * client's authentic bytes. r1091 faulted at method 0x1168 + * (SET_VERTEX_ATTRIBUTE_A(2)) with Data 00000000 in the emitted + * stream; this copy tells whether that zero is the client's own + * value or an emission artifact (drop/reloc/align). + */ + { + static u32 gr3d_raw_log; + u32 wi; + + if (gr3d_raw_log < 8) { + gr3d_raw_log++; + pr_info("vgsp-gr: 3D raw dump h=0x%x push=0x%llx words=%u\n", + req->h_object, req->push_va, + req->stream_n); + for (wi = 0; + wi + 16 <= req->stream_n && wi < 448; + wi += 16) + pr_info("vgsp-gr: 3D raw[%3u]: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x\n", + wi, + req->stream[wi + 0], + req->stream[wi + 1], + req->stream[wi + 2], + req->stream[wi + 3], + req->stream[wi + 4], + req->stream[wi + 5], + req->stream[wi + 6], + req->stream[wi + 7], + req->stream[wi + 8], + req->stream[wi + 9], + req->stream[wi + 10], + req->stream[wi + 11], + req->stream[wi + 12], + req->stream[wi + 13], + req->stream[wi + 14], + req->stream[wi + 15]); + } + } + /* * SESSION 153-CONTINUED-11: bounded raw window dump - the * exact C597 method stream the engine walks (program binds * 0x2014/0x2018+j*0x40, SET_PIPELINE_SHADER 0x2000+j*0x40, diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index f5ce23c..bd87d4c 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -44,6 +44,8 @@ #include <linux/workqueue.h> #include <linux/mm.h> #include <linux/vmalloc.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> #include <asm/unaligned.h> #include "nvidia-vgpu-vfio.h" @@ -1520,6 +1522,19 @@ struct sema_svc { #define SVC_STALLED_MAX 256 u64 stalled_vas[SVC_STALLED_MAX]; u32 stalled_va_count; + + /* + * SESSION 153-CONTINUED-56: the armed setup-hold's demand VA set + * (page-aligned, deduped per boot), exposed read-only to the demand + * tool via /sys/kernel/debug/vgsp/sema_setup_demand. State, not a + * log row: under vgsp-sema spam the `stalled VA #N` dmesg rows + * rotate out of the ring before the 3 s harvest reads them, so the + * setup-push pages were lost (r1090 needed a manual demand); the pin + * tool now reads this file directly each pass instead. + */ +#define SVC_SETUP_DEMAND_MAX 64 + u64 setup_demand_vas[SVC_SETUP_DEMAND_MAX]; + u32 setup_demand_count; }; static struct sema_svc svc; @@ -1553,6 +1568,107 @@ static void svc_log_stalled_va(u64 va) } /* + * SESSION 153-CONTINUED-56: record one page-aligned VA of the armed + * setup-hold demand set. Same caller as svc_log_stalled_va (the service + * thread); the debugfs reader publishes entries with a write barrier on the + * count, so a reader can never observe a torn entry (the count never + * decreases and an entry is stable once its slot is covered by the count). + */ +static void svc_setup_demand_record(u64 va) +{ + u32 i, n = svc.setup_demand_count; + + if (!va) + return; + for (i = 0; i < n; i++) + if (svc.setup_demand_vas[i] == va) + return; + if (n >= SVC_SETUP_DEMAND_MAX) + return; + svc.setup_demand_vas[n] = va; + smp_wmb(); + svc.setup_demand_count = n + 1; +} + +/* + * Read-only view of the setup-hold demand set for the pin tool: + * # sema setup-hold demand VAs (page-aligned): N + * 0x4021000 + * ... + */ +static int svc_setup_demand_show(struct seq_file *m, void *v) +{ + u32 i, n = READ_ONCE(svc.setup_demand_count); + + seq_printf(m, "# sema setup-hold demand VAs (page-aligned): %u\n", n); + for (i = 0; i < n && i < SVC_SETUP_DEMAND_MAX; i++) + seq_printf(m, "0x%llx\n", + (unsigned long long)svc.setup_demand_vas[i]); + return 0; +} + +static int svc_setup_demand_open(struct inode *inode, struct file *file) +{ + return single_open(file, svc_setup_demand_show, NULL); +} + +static const struct file_operations svc_setup_demand_fops = { + .owner = THIS_MODULE, + .open = svc_setup_demand_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* True when this module created the vgsp debugfs root (mirrors cuda bridge). */ +static bool svc_setup_demand_root_owned; + +static int svc_setup_demand_debugfs_init(void) +{ + struct dentry *root, *f; + + svc_setup_demand_root_owned = false; + root = debugfs_lookup("vgsp", NULL); + if (IS_ERR(root)) + root = NULL; + if (!root) { + root = debugfs_create_dir("vgsp", NULL); + if (IS_ERR_OR_NULL(root)) { + pr_warn("sema-svc: debugfs dir vgsp unavailable; sema_setup_demand not exposed\n"); + return -ENOENT; + } + svc_setup_demand_root_owned = true; + } + f = debugfs_create_file("sema_setup_demand", 0444, root, NULL, + &svc_setup_demand_fops); + if (IS_ERR_OR_NULL(f)) { + pr_warn("sema-svc: debugfs sema_setup_demand creation failed\n"); + if (svc_setup_demand_root_owned) + debugfs_lookup_and_remove("vgsp", NULL); + svc_setup_demand_root_owned = false; + return -ENOMEM; + } + dput(root); + pr_info("sema-svc: debugfs /sys/kernel/debug/vgsp/sema_setup_demand ready\n"); + return 0; +} + +static void svc_setup_demand_debugfs_fini(void) +{ + struct dentry *root; + + root = debugfs_lookup("vgsp", NULL); + if (IS_ERR_OR_NULL(root)) + return; + debugfs_lookup_and_remove("sema_setup_demand", root); + dput(root); + if (svc_setup_demand_root_owned) { + debugfs_lookup_and_remove("vgsp", NULL); + svc_setup_demand_root_owned = false; + } +} + +/* * Deferred readability probe for unreadable CE pushes that were consumed via * the fake-release fallback. The pump fakes immediately (work-before-release * cannot hold the channel); this queue re-attempts the read later in the @@ -22126,8 +22242,16 @@ static void svc_gr_setup_hold_arm(struct svc_channel *ch, u64 va, u32 idx, pr_info("sema-chan: GR setup hold h=0x%x entry=%u va=0x%llx len=%u armed (demanding 4K pages; pending until the pin lands, window %u ms)\n", ch->h_object, idx, va, len, gsp_sema_gr_setup_hold_ms); } - for (poff = 0; poff < len && poff < 0x10000u; poff += SEMA_PAGE_SIZE) + for (poff = 0; poff < len && poff < 0x10000u; poff += SEMA_PAGE_SIZE) { svc_log_stalled_va(page + poff); + /* + * SESSION 153-CONTINUED-56: also publish the page in the + * debugfs demand set the pin tool reads directly, so the + * demand no longer depends on the dmesg row surviving the + * ring rotation under vgsp-sema spam. + */ + svc_setup_demand_record(page + poff); + } } static bool svc_gr_setup_hold_active(const struct svc_channel *ch, u64 va, @@ -38751,6 +38875,8 @@ int gsp_sema_service_start(void) } if (gsp_cuda_bridge_init()) pr_warn("sema-svc: cuda bridge debugfs unavailable\n"); + if (svc_setup_demand_debugfs_init()) + pr_warn("sema-svc: setup-demand debugfs unavailable\n"); return 0; } @@ -38786,6 +38912,7 @@ void gsp_sema_service_stop(void) } /* Thread is gone: release the bridge's pending jobs and debugfs files. */ gsp_cuda_bridge_fini(); + svc_setup_demand_debugfs_fini(); /* A fresh session must not inherit shadowed bytes from the last one. */ svc_vas_free_all(); } diff --git a/tools/guest-diag/pin_gr_stream.py b/tools/guest-diag/pin_gr_stream.py index e224988..1acef4b 100644 --- a/tools/guest-diag/pin_gr_stream.py +++ b/tools/guest-diag/pin_gr_stream.py @@ -273,6 +273,24 @@ def _demand_loop(): zlen = int(m.group(2)) for zoff in range(0, min(zlen, 0x8000), 0x1000): track.setdefault(zva + zoff, [now, 0.0]) + # SESSION 153-CONTINUED-56: the armed setup-hold's demand VA set is + # exposed by the service as STATE (debugfs), not as a dmesg row, so + # it cannot race the ring rotation under vgsp-sema spam (r1090 lost + # the setup-push pages that way). Read it every pass and feed the + # same track/resend machinery: new VAs are sent this pass (last=0), + # existing ones keep the 20 s resend / 300 s expiry cadence. + try: + rr = subprocess.run( + ["sudo", "-n", "cat", + "/sys/kernel/debug/vgsp/sema_setup_demand"], + capture_output=True, text=True, timeout=10) + if rr.returncode == 0: + for m in re.finditer(r"0x[0-9a-f]+", rr.stdout or ""): + sva = int(m.group(0), 16) & ~0xfff + if sva: + track.setdefault(sva, [now, 0.0]) + except Exception: + pass for va in list(track): first, last = track[va] if now - first > 300.0: |
