summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 12:54:11 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 12:54:11 -0400
commitd3e35752e8d78a368940fc262b0013e1d50deed4 (patch)
tree89ef9a563768211381693dcb3debeb24cb8482de /kernel/gsp_sema_service.c
parent4ce77f9c375d2da7288d8d563c639f14df3948be (diff)
downloadopen-iov-d3e35752e8d78a368940fc262b0013e1d50deed4.tar.gz
open-iov-d3e35752e8d78a368940fc262b0013e1d50deed4.zip
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.
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c181
1 files changed, 131 insertions, 50 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 17b2ae4..75c5697 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -361,6 +361,7 @@ struct sema_svc {
u64 copy_watch_log; /* sema_copy_watch log budget */
u64 copy_pat_log; /* sema_copy_pat log budget */
u64 copy_dst_log; /* sema_copy_dst log budget */
+ u32 op_tr_src; /* provenance of last svc_op_translate */
u64 push_pat_log; /* push-content pattern budget */
u64 dma_skip_log; /* unrecognized-DMA budget */
u64 grce_log; /* GRCE inline-write budget */
@@ -1852,7 +1853,7 @@ static void svc_rebuild(struct nv_vgpu_device *vgpu)
svc.vidmem_writes, svc_ring_n, svc_pb_n, svc_pb_passes,
svc.pin_n, svc.pin_drop, svc.ipin_n, svc.ipin_drop);
/* show a few entries so mappings can be verified from dmesg */
- {
+ if (gsp_sema_dbg) {
u32 shown;
for (shown = 0; shown < svc.map_n && shown < 8; shown++)
@@ -1971,15 +1972,19 @@ static int svc_op_translate(struct nv_vgpu_device *vgpu, u64 va, u64 *addr,
u64 pa = 0;
int ap = SVC_APERTURE_SYS;
+ svc.op_tr_src = 0;
+
if (!svc_pin_lookup_any(va, &pa, &ap)) {
*addr = pa;
*aperture = (ap == SVC_APERTURE_FB) ? CE_APERTURE_VID :
CE_APERTURE_SYS;
+ svc.op_tr_src = 1;
return 0;
}
if (!svc_map_lookup(va, &pa)) {
*addr = pa;
*aperture = CE_APERTURE_SYS;
+ svc.op_tr_src = 2;
return 0;
}
/*
@@ -1992,12 +1997,14 @@ static int svc_op_translate(struct nv_vgpu_device *vgpu, u64 va, u64 *addr,
*addr = pa + (va & 0xfff);
*aperture = (ap == SVC_APERTURE_FB) ? CE_APERTURE_VID :
CE_APERTURE_SYS;
+ svc.op_tr_src = 3;
return 0;
}
if (!svc_walk_discovered(vgpu, va & ~0xfffULL, &pa, &ap)) {
*addr = pa + (va & 0xfff);
*aperture = (ap == SVC_APERTURE_FB) ? CE_APERTURE_VID :
CE_APERTURE_SYS;
+ svc.op_tr_src = 4;
return 0;
}
/*
@@ -2018,6 +2025,7 @@ static int svc_op_translate(struct nv_vgpu_device *vgpu, u64 va, u64 *addr,
pr_info("sema-op-tr: va=0x%llx -> pa=0x%llx\n",
va, *addr);
}
+ svc.op_tr_src = 5;
return 0;
}
/*
@@ -2032,6 +2040,25 @@ static int svc_op_translate(struct nv_vgpu_device *vgpu, u64 va, u64 *addr,
}
/*
+ * Does a destination address fall inside either 16 KB watch window
+ * (sema_copy_dst / sema_copy_dst2)? The window is what makes the page-table
+ * write chain observable: root PD, child tables and PTE pages all sit in
+ * distinct pages a whole run apart.
+ */
+static bool svc_dst_watched(u64 dst)
+{
+ if (gsp_sema_copy_dst &&
+ dst >= (gsp_sema_copy_dst & ~0x3fffULL) &&
+ dst < (gsp_sema_copy_dst & ~0x3fffULL) + 0x4000)
+ return true;
+ if (gsp_sema_copy_dst2 &&
+ dst >= (gsp_sema_copy_dst2 & ~0x3fffULL) &&
+ dst < (gsp_sema_copy_dst2 & ~0x3fffULL) + 0x4000)
+ return true;
+ return false;
+}
+
+/*
* Write `count` elements of `value` (element size `elem`) starting at
* `addr`, in vidmem or guest RAM depending on the aperture DST_TYPE
* selected. Returns 0 on success.
@@ -2064,6 +2091,17 @@ static int svc_fill(struct nv_vgpu_device *vgpu, u64 addr, u64 value, u32 elem,
aperture = aper;
}
+ if (gsp_sema_dbg && svc_dst_watched(addr) && svc.copy_dst_log < 192) {
+ u8 pb[8];
+
+ memset(pb, 0, sizeof(pb));
+ memcpy(pb, pat, sizeof(pb));
+ svc.copy_dst_log++;
+ pr_info("sema-copy-dst: FILL dst=0x%llx off=0x%llx total=%zu elem=%u count=%u value=0x%llx prov=%u pat=%*phN h=0x%x\n",
+ addr, addr & 0xfffULL, total, elem, count, value,
+ svc.op_tr_src, elem, pb, svc.cur_ch);
+ }
+
if (aperture == CE_APERTURE_VID) {
u8 *base = vgpu->bars[1].vaddr;
size_t size = vgpu->bars[1].size;
@@ -2110,7 +2148,7 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
u32 aper;
if (svc_op_translate(vgpu, dst, &pa, &aper)) {
- if (svc.op_tr_log < 64) {
+ if (gsp_sema_dbg && svc.op_tr_log < 64) {
svc.op_tr_log++;
pr_info("sema-tr-miss: DST va=0x%llx h=0x%x\n",
dst, svc.cur_ch);
@@ -2125,7 +2163,7 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
u32 aper;
if (svc_op_translate(vgpu, src, &pa, &aper)) {
- if (svc.op_tr_log < 64) {
+ if (gsp_sema_dbg && svc.op_tr_log < 64) {
svc.op_tr_log++;
pr_info("sema-tr-miss: SRC va=0x%llx h=0x%x\n",
src, svc.cur_ch);
@@ -2144,8 +2182,9 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
* source or destination starts with that 8-byte value is logged too,
* whatever its size - this finds the push carrying a known payload.
*/
- if ((gsp_sema_copy_watch && total == gsp_sema_copy_watch) ||
- gsp_sema_copy_pat) {
+ if (gsp_sema_dbg &&
+ ((gsp_sema_copy_watch && total == gsp_sema_copy_watch) ||
+ gsp_sema_copy_pat)) {
u8 sb[8] = {0}, db[8] = {0};
if (src_aperture == CE_APERTURE_VID) {
@@ -2164,7 +2203,8 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
} else {
svc_read(vgpu, dst, db, 8);
}
- if (gsp_sema_copy_watch && total == gsp_sema_copy_watch &&
+ if (gsp_sema_dbg && gsp_sema_copy_watch &&
+ total == gsp_sema_copy_watch &&
svc.copy_watch_log < 64) {
svc.copy_watch_log++;
pr_info("sema-copy-watch: total=%zu dst=0x%llx dap=%u src=0x%llx sap=%u src8=%02x %02x %02x %02x %02x %02x %02x %02x dst8_before=%02x %02x %02x %02x %02x %02x %02x %02x\n",
@@ -2173,7 +2213,8 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
sb[6], sb[7], db[0], db[1], db[2], db[3],
db[4], db[5], db[6], db[7]);
}
- if (gsp_sema_copy_pat && svc.copy_pat_log < 64) {
+ if (gsp_sema_dbg && gsp_sema_copy_pat &&
+ svc.copy_pat_log < 64) {
u64 sv = 0, dv = 0;
memcpy(&sv, sb, 8);
@@ -2194,12 +2235,13 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
/*
* Destination-keyed watch: dump the source bytes of every copy whose
- * destination lies in gsp_sema_copy_dst's page. This reads the
- * page-table entries the guest writes into vidmem directly.
+ * destination lies in the 16 KB window at gsp_sema_copy_dst. This
+ * reads the page-table entries the guest writes into vidmem directly,
+ * whatever the mechanism; `prov` names which translation layer
+ * answered for the source (1 pin, 2 map, 3 vaspaces, 4 discovered,
+ * 5 targeted RAM resolve).
*/
- if (gsp_sema_copy_dst &&
- (dst & ~0xfffULL) == (gsp_sema_copy_dst & ~0xfffULL) &&
- svc.copy_dst_log < 32) {
+ if (gsp_sema_dbg && svc_dst_watched(dst) && svc.copy_dst_log < 192) {
u8 peek[32];
u32 n = total < sizeof(peek) ? (u32)total : sizeof(peek);
@@ -2213,9 +2255,9 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
svc_read(vgpu, src, peek, n);
}
svc.copy_dst_log++;
- pr_info("sema-copy-dst: dst=0x%llx off=0x%llx total=%zu src=0x%llx sap=%u data=%*phN h=0x%x\n",
+ pr_info("sema-copy-dst: dst=0x%llx off=0x%llx total=%zu src=0x%llx sap=%u prov=%u data=%*phN h=0x%x\n",
dst, dst & 0xfffULL, total, src, src_aperture,
- n, peek, svc.cur_ch);
+ svc.op_tr_src, n, peek, svc.cur_ch);
}
for (o = 0; o < total; ) {
@@ -2252,7 +2294,8 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
o += chunk;
}
- if (gsp_sema_copy_watch && total == gsp_sema_copy_watch &&
+ if (gsp_sema_dbg && gsp_sema_copy_watch &&
+ total == gsp_sema_copy_watch &&
svc.copy_watch_log <= 64) {
u8 da[8] = {0};
@@ -2268,6 +2311,21 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
da[0], da[1], da[2], da[3], da[4], da[5], da[6],
da[7], dst);
}
+ if (gsp_sema_dbg && svc_dst_watched(dst) && svc.copy_dst_log <= 192) {
+ u8 da[16] = {0};
+ u32 n = total < sizeof(da) ? (u32)total : sizeof(da);
+
+ if (dst_aperture == CE_APERTURE_VID) {
+ u8 *base = vgpu->bars[1].vaddr;
+
+ if (base && dst + n <= vgpu->bars[1].size)
+ memcpy(da, base + dst, n);
+ } else {
+ svc_read(vgpu, dst, da, n);
+ }
+ pr_info("sema-copy-dst: after dst=0x%llx dst16=%*phN\n",
+ dst, n, da);
+ }
return 0;
}
@@ -2286,7 +2344,7 @@ static int svc_grce_inline_write(struct nv_vgpu_device *vgpu, u64 dst_va,
if (!bytes || bytes > (1u << 20))
return -EINVAL;
if (svc_lookup_trusted(vgpu, dst_va & ~0xfffULL, &pa, &ap)) {
- if (svc.grce_log < 16) {
+ if (gsp_sema_dbg && svc.grce_log < 16) {
svc.grce_log++;
pr_info("sema-grce: inline write dst=0x%llx bytes=%u UNRESOLVED h=0x%x\n",
dst_va, bytes, ch_h);
@@ -2295,7 +2353,8 @@ static int svc_grce_inline_write(struct nv_vgpu_device *vgpu, u64 dst_va,
}
svc_pin_store(dst_va & ~0xfffULL, pa, ap);
pa += dst_va & 0xfff;
- if (svc.grce_log < (gsp_sema_ops_log > 64 ? gsp_sema_ops_log : 64)) {
+ if (gsp_sema_dbg &&
+ svc.grce_log < (gsp_sema_ops_log > 64 ? gsp_sema_ops_log : 64)) {
u32 n = bytes >= 8 ? 8 : bytes;
svc.grce_log++;
@@ -2348,15 +2407,16 @@ static void svc_run_ops(struct nv_vgpu_device *vgpu, struct svc_memset_op *ops,
svc.memsets_nomap++;
else
svc.memsets_fail++;
- if (m->bytes == 256 && svc.sem256_log < 64) {
+ if (gsp_sema_dbg && m->bytes == 256 && svc.sem256_log < 64) {
svc.sem256_log++;
pr_info("sema-256: type=%u dst=0x%llx src=0x%llx bytes=%llu rc=%d h=0x%x done=%llu nomap=%llu fail=%llu\n",
m->type, m->dst, m->src, m->bytes, rc, ch_h,
svc.memsets_done, svc.memsets_nomap,
svc.memsets_fail);
}
- if ((rc == 0 && svc.memsets_done <= gsp_sema_ops_log) ||
- (rc != 0 && svc.memsets_fail + svc.memsets_nomap <= 64))
+ if (gsp_sema_dbg &&
+ ((rc == 0 && svc.memsets_done <= gsp_sema_ops_log) ||
+ (rc != 0 && svc.memsets_fail + svc.memsets_nomap <= 64)))
pr_info("sema-svc: %s dst=0x%llx value=0x%llx elem=%u count=%u bytes=%llu phys=%u ap=%u src=0x%llx srcphys=%u srcap=%u rc=%d h=0x%x\n",
m->type == 1 ? "memcopy" : "memset",
m->dst, m->value, m->elem, m->count,
@@ -2484,12 +2544,12 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h,
}
}
spin_unlock_irqrestore(&svc.chan_lock, flags);
- if (svc.counter_rel_dbg < 96) {
+ if (gsp_sema_dbg && svc.counter_rel_dbg < 96) {
svc.counter_rel_dbg++;
pr_info("sema-chan: rel-apply h=0x%x va=0x%llx pay=%u -> slot pending\n",
h, sem_va, payload);
}
- } else if (svc.counter_rel_dbg < 96) {
+ } else if (gsp_sema_dbg && svc.counter_rel_dbg < 96) {
svc.counter_rel_dbg++;
pr_info("sema-chan: rel-apply h=0x%x va=0x%llx pay=%u -> no slot registered\n",
h, sem_va, payload);
@@ -2498,7 +2558,7 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h,
}
if (svc_read_ap(vgpu, pa, SVC_APERTURE_SYS, &cur, sizeof(cur))) {
- if (svc.counter_rel_dbg < 32) {
+ if (gsp_sema_dbg && svc.counter_rel_dbg < 32) {
svc.counter_rel_dbg++;
pr_info("sema-chan: rel-apply h=0x%x pa=0x%llx pay=%u -> read failed\n",
h, pa, payload);
@@ -2506,7 +2566,7 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h,
return;
}
if (payload <= cur || payload - cur > 0x100000) {
- if (svc.counter_rel_dbg < 32) {
+ if (gsp_sema_dbg && svc.counter_rel_dbg < 32) {
svc.counter_rel_dbg++;
pr_info("sema-chan: rel-apply h=0x%x pa=0x%llx pay=%u cur=%u -> skip\n",
h, pa, payload, cur);
@@ -2520,7 +2580,7 @@ static void svc_counter_release_apply(struct nv_vgpu_device *vgpu, u32 h,
svc.counter_rel_applied++;
svc.gr_rel_applied++;
svc.post_hint_until = jiffies + 10 * HZ;
- if (svc.counter_rel_dbg < 32) {
+ if (gsp_sema_dbg && svc.counter_rel_dbg < 32) {
svc.counter_rel_dbg++;
pr_info("sema-chan: rel-apply h=0x%x pa=0x%llx pay=%u cur=%u -> written\n",
h, pa, payload, cur);
@@ -2561,7 +2621,7 @@ static void svc_counter_flush_pending(struct nv_vgpu_device *vgpu,
svc.counter_rel_applied++;
svc.gr_rel_applied++;
svc.post_hint_until = jiffies + 10 * HZ;
- if (svc.counter_rel_dbg < 96) {
+ if (gsp_sema_dbg && svc.counter_rel_dbg < 96) {
svc.counter_rel_dbg++;
pr_info("sema-chan: rel-flush h=0x%x pa=0x%llx pay=%u cur=%u -> written\n",
ch->h_object, ch->counter_pa, payload, cur);
@@ -2680,7 +2740,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
memset(&st, 0, sizeof(st));
svc.pages_decoded++;
- if (ch->engine_type && svc_dbg_streams < 24) {
+ if (gsp_sema_dbg && ch->engine_type && svc_dbg_streams < 24) {
svc_dbg_streams++;
pr_info("sema-dbg: stream h=0x%x eng=%u va=0x%llx len=%u allow=%d w=%08x %08x %08x %08x %08x %08x %08x %08x\n",
ch->h_object, ch->engine_type, push_va, len, allow_ops,
@@ -2700,7 +2760,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* in the push). This finds the submission carrying a known payload
* even when its method encoding is not (yet) decoded into an op.
*/
- if (gsp_sema_copy_pat && svc.push_pat_log < 32) {
+ if (gsp_sema_dbg && gsp_sema_copy_pat && svc.push_pat_log < 32) {
u32 o;
for (o = 0; o + 8 <= len; o += 4) {
@@ -2745,7 +2805,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
svc_grce_inline_write(vgpu, st.offset_out,
buf + off + 4, bytes,
ch->h_object);
- } else if (svc.grce_log < 16) {
+ } else if (gsp_sema_dbg && svc.grce_log < 16) {
svc.grce_log++;
pr_info("sema-grce: inline data not run (trusted=%d allow=%d have_out=%d line=%u) h=0x%x\n",
trusted, allow_ops, st.have_out,
@@ -3070,8 +3130,8 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
u32 dma = v0;
u32 transfer = DMA_DATA_TRANSFER_TYPE(dma);
- if (ch->h_object && svc.lda_log <
- (gsp_sema_ops_log > 48 ? gsp_sema_ops_log : 48)) {
+ if (gsp_sema_dbg && ch->h_object &&
+ svc.lda_log < (gsp_sema_ops_log > 48 ? gsp_sema_ops_log : 48)) {
svc.lda_log++;
pr_info("sema-lda: h=0x%x eng=%u push=0x%llx inj=%u allow=%u dma=0x%08x xfer=%u remap=%u dpitch=%u dstphys=%u srcphys=%u sem=%u out=0x%llx in=0x%llx line=%u have_out=%u have_in=%u have_remap=%u have_sem=%u ops=%u\n",
ch->h_object, ch->engine_type, push_va,
@@ -3123,7 +3183,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
m->src_aperture = st.have_src_mode ?
st.src_phys_mode : CE_APERTURE_VID;
n_ops++;
- } else if (svc.dma_skip_log < 32) {
+ } else if (gsp_sema_dbg && svc.dma_skip_log < 32) {
/*
* A launch that looks like a transfer but
* carries no branch we execute: no source
@@ -3133,12 +3193,18 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* missing OFFSET_IN run, or a phys-mode
* value that never arrived).
*/
+ u32 dl = len < 192 ? len : 192;
+
svc.dma_skip_log++;
- pr_info("sema-dma-skip: h=0x%x dma=0x%08x line=%u in=0x%llx out=0x%llx have_in=%u have_out=%u have_remap=%u have_sem=%u\n",
- ch->h_object, dma, st.line_length,
+ pr_info("sema-dma-skip: h=0x%x push=0x%llx off=0x%x dma=0x%08x line=%u in=0x%llx out=0x%llx have_in=%u have_out=%u have_remap=%u have_sem=%u\n",
+ ch->h_object, push_va, off, dma,
+ st.line_length,
st.offset_in, st.offset_out,
st.have_in, st.have_out,
st.have_remap, st.have_sem);
+ if (svc.dma_skip_log <= 8)
+ pr_info("sema-dma-skip: raw len=%u %*phN\n",
+ len, dl, buf);
}
}
@@ -3214,7 +3280,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
* only the copy itself.
*/
if (allow_ops && n_ops && !gsp_sema_skip_ops) {
- if (ch->engine_type == 0 &&
+ if (gsp_sema_dbg && ch->engine_type == 0 &&
svc.sem256_log < 64) {
svc.sem256_log++;
pr_info("sema-sem0: h=0x%x va=0x%llx allow=%u n_ops=%u skip=%u\n",
@@ -3285,7 +3351,7 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
off += 4 + count * 4;
}
- if (ch->h_object && svc.entry_log < 512) {
+ if (gsp_sema_dbg && ch->h_object && svc.entry_log < 512) {
svc.entry_log++;
{
u8 tail[24];
@@ -3371,8 +3437,9 @@ static void svc_apply_pending(struct nv_vgpu_device *vgpu)
p->op ? cur + p->payload : p->payload)) {
svc.releases_applied++;
svc.post_hint_until = jiffies + 10 * HZ;
- pr_info("sema-svc: deferred release va=0x%llx payload=%u (was cur=%u)\n",
- p->va, p->payload, cur);
+ if (gsp_sema_dbg)
+ pr_info("sema-svc: deferred release va=0x%llx payload=%u (was cur=%u)\n",
+ p->va, p->payload, cur);
svc_pending[i] = svc_pending[--svc_pending_n];
continue;
}
@@ -3517,8 +3584,9 @@ static u32 __maybe_unused __svc_apply_page_data_disabled(struct nv_vgpu_device *
svc.releases_jumped++;
pr_info("sema-svc: applied va=0x%llx pa=0x%llx payload=%u (gap: cur=%u)\n",
va, pa, payload, cur32);
- } else if (svc.releases_applied <= 64 ||
- (svc.releases_applied % 100) == 0) {
+ } else if (gsp_sema_dbg &&
+ (svc.releases_applied <= 64 ||
+ (svc.releases_applied % 100) == 0)) {
pr_info("sema-svc: applied va=0x%llx pa=0x%llx payload=%u\n",
va, pa, payload);
}
@@ -3985,7 +4053,8 @@ static void svc_notify_complete(struct nv_vgpu_device *vgpu,
*/
if (!svc_write_ap(vgpu, base, ch->notifier_as, zero, sizeof(zero))) {
ch->notified++;
- if (ch->notified <= 4 || (ch->notified % 10000) == 0)
+ if (gsp_sema_dbg &&
+ (ch->notified <= 4 || (ch->notified % 10000) == 0))
pr_info("sema-chan: notifier cleared h=0x%x info32=0x%x status=0x%x (n=%llu)\n",
ch->h_object, info32, status, ch->notified);
@@ -4078,6 +4147,15 @@ unsigned gsp_sema_gr_grace_ms = 8000;
bool gsp_sema_fake_rel;
/*
+ * Master diagnostic switch for the per-push/per-doorbell/per-op tracing.
+ * Off by default: a healthy boot must leave dmesg quiet (boot stats and
+ * state changes only). Enable per run through the module parameter when
+ * instrumenting; the finer-grained watch knobs (ops_log, copy_watch,
+ * copy_pat, copy_dst) only take effect while this is on.
+ */
+bool gsp_sema_dbg;
+
+/*
* Skip executing a push's collected work (CE memsets/copies into the vidmem
* shadow) while still applying its semaphore release. The client only ever
* observes the release; the shadow writes exist so the emulation can walk
@@ -4108,6 +4186,7 @@ u64 gsp_sema_copy_pat;
* guest writes to vidmem (32-byte PD updates) and learn their encoding.
*/
u64 gsp_sema_copy_dst;
+u64 gsp_sema_copy_dst2;
/*
* Grace window (ms) an untranslatable CE entry stays pending before the
@@ -4559,7 +4638,7 @@ static void svc_init_expected_payload(struct nv_vgpu_device *vgpu,
if (cur < 0x100000) {
ch->expected_sem_payload = cur + 1;
- if (ch->logged_expected != cur) {
+ if (gsp_sema_dbg && ch->logged_expected != cur) {
ch->logged_expected = cur;
pr_info("sema-svc: ch=0x%x rank=%u pool sem @0x%llx cur=%u -> expected=%u\n",
ch->h_object, ch->ce_index, pool_va, cur,
@@ -4607,7 +4686,7 @@ static void svc_counter_publish(struct nv_vgpu_device *vgpu,
&val, sizeof(val)))
return;
ch->counter_last = val;
- if (svc.counter_pub_dbg < 48) {
+ if (gsp_sema_dbg && svc.counter_pub_dbg < 48) {
svc.counter_pub_dbg++;
pr_info("sema-chan: counter publish h=0x%x pa=0x%llx val=%u (was %u)\n",
ch->h_object, ch->counter_pa, val, cur);
@@ -4775,7 +4854,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
/* GP_ENTRY1.LENGTH[30:10], in dwords */
len = ((e1 >> 10) & 0x1fffff) << 2;
- if (svc.gpfifo_entry_log < 32) {
+ if (gsp_sema_dbg && svc.gpfifo_entry_log < 32) {
pr_info("sema-chan: entry[%llu] raw=%08x%08x va=0x%llx len=%u\n",
idx, e1, e0, va, len);
svc.gpfifo_entry_log++;
@@ -5445,9 +5524,10 @@ static void svc_handle_map_add(void)
svc_lat_store(req.va + off, req.pa + off, ap);
}
rewound = true;
- pr_info_ratelimited("sema-svc: injected mapping va=0x%llx -> pa=0x%llx len=0x%llx (%s)\n",
- req.va, req.pa, req.len,
- ap == SVC_APERTURE_FB ? "vidmem" : "sysmem");
+ if (gsp_sema_dbg)
+ pr_info_ratelimited("sema-svc: injected mapping va=0x%llx -> pa=0x%llx len=0x%llx (%s)\n",
+ req.va, req.pa, req.len,
+ ap == SVC_APERTURE_FB ? "vidmem" : "sysmem");
}
/*
@@ -5749,8 +5829,9 @@ static int svc_thread(void *arg)
svc.last_hint = jiffies;
rc = gsp_rm_post_all_events(vgpu);
- pr_info_ratelimited("sema-svc: completion hint rc=%d\n",
- rc);
+ if (gsp_sema_dbg)
+ pr_info_ratelimited("sema-svc: completion hint rc=%d\n",
+ rc);
}
/*
@@ -5801,7 +5882,7 @@ void gsp_sema_service_doorbell(u32 token)
if (svc.task)
wake_up_process(svc.task);
- if (svc.doorbell_log < 64) {
+ if (gsp_sema_dbg && svc.doorbell_log < 64) {
pr_info("sema-svc: doorbell token=0x%x runlist=%u vector=%u (count=%llu)\n",
token, (token >> 16) & 0x7f, token & 0xfff,
svc.doorbell_count);