summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c55
-rw-r--r--kernel/gsp_sema_service.h7
-rw-r--r--kernel/main.c9
3 files changed, 69 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++;
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index b7cc6fa..3b85591 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -70,4 +70,11 @@ void gsp_sema_service_doorbell(u32 token);
*/
extern bool gsp_sema_gr_rings;
+/*
+ * Acknowledge tracking-semaphore releases from CE pushes the pump could not
+ * read: write the expected payload into the channel's pool semaphore so the
+ * driver's wait clears immediately instead of after the content sweep.
+ */
+extern bool gsp_sema_fake_rel;
+
#endif /* _GSP_SEMA_SERVICE_H_ */
diff --git a/kernel/main.c b/kernel/main.c
index 0bd4826..726b4bf 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -2432,6 +2432,15 @@ module_param_named(sema_gr_rings, gsp_sema_gr_rings, bool, 0644);
MODULE_PARM_DESC(sema_gr_rings, "Auto-discover+pin GR channel rings (default 1)");
/*
+ * Acknowledge releases from unreadable CE pushes directly (tracking-semaphore
+ * fallback). The push's data writes are lost either way when the content
+ * rescue cannot find the page; writing the expected payload keeps the
+ * driver's progress waits from timing out on the rescue latency.
+ */
+module_param_named(sema_fake_rel, gsp_sema_fake_rel, bool, 0644);
+MODULE_PARM_DESC(sema_fake_rel, "Acknowledge unreadable CE releases directly (default 0)");
+
+/*
* Debug: inject a verified {GPU VA -> guest PA} translation into the
* semaphore service (used when the client's mapping cannot be discovered
* from guest structures):