summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-31 02:34:15 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-31 02:34:15 -0400
commit667491fe59737ebfb327804d361b2eb0a8b170bb (patch)
treec265755724f5f61449da84f3779c4d182a2fd025 /kernel/gsp_sema_service.c
parent5620ed076c87be100be87432c6d5b3035a46ed6f (diff)
downloadopen-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
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c129
1 files changed, 128 insertions, 1 deletions
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();
}