From 7d21a9fa1e7798e1a4d2938ebee307f6da6e4c74 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 30 Sep 2026 12:54:11 -0400 Subject: sema-svc: gate per-push/per-doorbell/RPC tracing behind default-off sema_dbg A healthy run left dmesg dominated by per-operation lines (sema-push, sema-lda, sema-chan rel-apply, sema-grce, DOORBELL/BAR writes, GSPRM per-RPC lines, the teardown garbage-element stream). Introduce the module parameter sema_dbg (default 0) and route every high-frequency diagnostic through it; the finer-grained watch knobs (sema_ops_log, sema_copy_watch, sema_copy_pat, sema_copy_dst, sema_copy_dst2) only take effect while it is on. Boot stats, channel registrations, pin events and state changes stay unconditional. Also carries the per-side translation provenance (op_tr_src, printed as prov= in the destination-window watch) and the 16 KB destination window used to observe the guest's page-table writes. Verified: fresh boot + full cdt2 smoke test (64/64, ALL OK) leaves a 520-line dmesg with zero per-push/per-doorbell/per-RPC lines. --- kernel/main.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'kernel/main.c') diff --git a/kernel/main.c b/kernel/main.c index d6e6c9d..dd38402 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -717,7 +717,9 @@ static ssize_t nv_vgpu_vfio_dev_read(struct vfio_device *vdev, char __user *buf, struct nv_vgpu_device *vgpu = container_of(vdev, struct nv_vgpu_device, vfio_dev); loff_t pos = *ppos; - pr_info("gsp-resman-vfio: VFIO device read count=%zu pos=%lld (0x%llx)\n", count, pos, pos); + if (gsp_sema_dbg) + pr_info("gsp-resman-vfio: VFIO device read count=%zu pos=%lld (0x%llx)\n", + count, pos, pos); /* Config space region: VFIO_PCI_INDEX_TO_OFFSET(VFIO_PCI_CONFIG_REGION_INDEX) = 0x70000000000 */ if (pos >= 0x70000000000ULL && pos < 0x70000000000ULL + 4096) { @@ -772,7 +774,9 @@ static ssize_t nv_vgpu_vfio_dev_write(struct vfio_device *vdev, const char __use struct nv_vgpu_device *vgpu = container_of(vdev, struct nv_vgpu_device, vfio_dev); loff_t pos = *ppos; - pr_info_ratelimited("gsp-resman-vfio: VFIO device write count=%zu pos=%lld (0x%llx)\n", count, pos, pos); + if (gsp_sema_dbg) + pr_info_ratelimited("gsp-resman-vfio: VFIO device write count=%zu pos=%lld (0x%llx)\n", + count, pos, pos); /* Config space region - route through the per-register filter so the * guest can only modify writable registers (not vendor/device IDs, @@ -802,14 +806,14 @@ static ssize_t nv_vgpu_vfio_dev_write(struct vfio_device *vdev, const char __use if (copy_from_user(tmp, buf, count)) return -EFAULT; - if (bar0_log < 64 || (u64)pos == 0x88704) { + if ((u64)pos == 0x88704 || (gsp_sema_dbg && bar0_log < 64)) { static u32 db_log; u64 v = 0; memcpy(&v, tmp, count); if ((u64)pos == 0x88704) { - if (db_log < 512) { + if (gsp_sema_dbg && db_log < 512) { pr_info("gsp-resman-vfio: DOORBELL write pos=0x%llx size=%zu val=0x%llx\n", (u64)pos, count, v); db_log++; @@ -837,7 +841,7 @@ static ssize_t nv_vgpu_vfio_dev_write(struct vfio_device *vdev, const char __use u64 bar1_off = (u64)pos - (1ULL << 40); static u32 bar1_log; - if (bar1_log < 64) { + if (gsp_sema_dbg && bar1_log < 64) { u64 v = 0; memcpy(&v, buf, count); @@ -2449,6 +2453,17 @@ MODULE_PARM_DESC(sema_fake_rel, "Acknowledge unreadable CE releases directly (de module_param_named(sema_skip_ops, gsp_sema_skip_ops, bool, 0644); MODULE_PARM_DESC(sema_skip_ops, "Apply releases without executing pushed memsets (default 0)"); +/* + * Master diagnostic switch for the per-push/per-doorbell/per-op tracing + * (sema-push, sema-lda, sema-chan rel-apply, sema-grce, DOORBELL, the + * GSPRM per-RPC lines, ...). Off by default so a healthy boot leaves the + * kernel log quiet; turn it on when instrumenting a cycle. The watch knobs + * below (ops_log, copy_watch, copy_pat, copy_dst) only take effect while + * this is on. + */ +module_param_named(sema_dbg, gsp_sema_dbg, bool, 0644); +MODULE_PARM_DESC(sema_dbg, "Verbose per-push/per-RPC emulation tracing (default 0)"); + /* * Executed-op log cap: how many CE fills/copies are logged with full * operands. Raise it (e.g. 4096) to audit a data path; the default keeps a @@ -2483,6 +2498,14 @@ MODULE_PARM_DESC(sema_copy_pat, "8-byte pattern matched in copy src/dst and push module_param_named(sema_copy_dst, gsp_sema_copy_dst, ullong, 0644); MODULE_PARM_DESC(sema_copy_dst, "Dump source bytes of copies landing in this page (default 0)"); +/* + * Same watch, second 16 KB-aligned window (0 = off). Two windows let one + * run cover both the page-directory table and the page-table page it points + * into, e.g. 0x208000 and 0x230000. + */ +module_param_named(sema_copy_dst2, gsp_sema_copy_dst2, ullong, 0644); +MODULE_PARM_DESC(sema_copy_dst2, "Second destination window for sema_copy_dst (default 0)"); + /* * Grace window (ms) an untranslatable CE entry stays pending before the * fallback acknowledges its release and consumes it. Its work must run before -- cgit v1.2.3