summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 12:30:57 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 12:30:57 -0400
commit3fae97a4422829930e52cb0839b7593006def7bf (patch)
tree109a96c013e29048241cc6fa2e60e83611b38b27 /kernel/gsp_sema_service.c
parent23c3754ecb231cb7b57bf2f2a81f241a91b09189 (diff)
downloadopen-iov-3fae97a4422829930e52cb0839b7593006def7bf.tar.gz
open-iov-3fae97a4422829930e52cb0839b7593006def7bf.zip
sema-svc: optional CE release fallback for unreadable pushes (sema_fake_rel)
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 72480a2..343981c 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -330,6 +330,7 @@ struct sema_svc {
u64 last_miss_va;
u64 releases_stale; /* payload <= current */
u64 releases_jumped; /* applied with gap > 1 */
+ u64 releases_faked; /* skipped-entry fallback */
u64 builds;
u64 gpfifo_entries_done; /* entries consumed via GPFIFO */
u64 gpfifo_nomap; /* GPFIFO/pushbuf VA not mapped */
@@ -1704,11 +1705,11 @@ static void svc_rebuild(struct nv_vgpu_device *vgpu)
svc.releases_stale, svc.releases_jumped,
svc.walks_ok, svc.walks_ok + svc.walks_miss, svc.lat_hits,
svc_scan_cursor);
- pr_info("sema-svc: pages=%llu pushes=%llu pending=%llu nomap=%llu memset=%llu/%llu/%llu ringops=%llu denied=%llu false=%llu skip=%llu\n",
+ pr_info("sema-svc: pages=%llu pushes=%llu pending=%llu nomap=%llu memset=%llu/%llu/%llu ringops=%llu denied=%llu false=%llu skip=%llu faked=%llu\n",
svc.pages_decoded, svc.pushes_seen, svc.pushes_pending,
svc.pushes_nomap, svc.memsets_done, svc.memsets_nomap,
svc.memsets_fail, svc.ring_ops, svc.ops_denied,
- svc.false_trans, svc.gpfifo_skipped);
+ svc.false_trans, svc.gpfifo_skipped, svc.releases_faked);
pr_info("sema-svc: gpfifo done=%llu nomap=%llu vidmem_writes=%llu ring_auto=%u pb=%u/%u\n",
svc.gpfifo_entries_done, svc.gpfifo_nomap,
svc.vidmem_writes, svc_ring_n, svc_pb_n, svc_pb_passes);
@@ -3172,6 +3173,17 @@ static int svc_chan_entry0(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
bool gsp_sema_gr_rings = true;
+/*
+ * CE release fallback: when a push carrying a tracking-semaphore release
+ * cannot be read (and the content rescue failed), advance the channel's
+ * tracking semaphore to the expected payload directly. The push's data
+ * writes are lost either way - the rescue path only applies the release,
+ * never the work - so acknowledging the release is strictly better than
+ * making the driver wait for the multi-second full-RAM sweep. Off by
+ * default; enabled per run through the module parameter.
+ */
+bool gsp_sema_fake_rel;
+
static unsigned long svc_gr_ring_tried; /* ranks that got a diagnostic line */
static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
@@ -3878,6 +3890,45 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
ch->h_object, va, len,
ch->rescue_fail);
ch->rescue_fail = 0;
+ /*
+ * The entry carried a tracking-
+ * semaphore release we could not
+ * read. Acknowledge it the way the
+ * GPU would so the driver's wait
+ * clears in one pass.
+ */
+ if (gsp_sema_fake_rel &&
+ ch->engine_type &&
+ ch->expected_sem_payload) {
+ u64 pool_va =
+ 0x121000000ULL +
+ 4ULL * ch->ce_index;
+ u64 spa = 0;
+ int sap =
+ SVC_APERTURE_SYS;
+ u32 scur = 0;
+
+ if (!svc_lookup_trusted(
+ vgpu,
+ pool_va,
+ &spa,
+ &sap) &&
+ !svc_read_ap(vgpu,
+ spa, sap,
+ &scur,
+ sizeof(scur)) &&
+ scur < ch->expected_sem_payload) {
+ u32 nv =
+ ch->expected_sem_payload;
+
+ if (!svc_write_ap(vgpu,
+ spa, sap,
+ &nv,
+ sizeof(nv)))
+ svc.releases_applied++;
+ }
+ svc.releases_faked++;
+ }
ch->last_get = (idx + 1) %
ch->gpfifo_entries;
svc.gpfifo_skipped++;