summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 06:01:06 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 06:01:06 -0400
commitb37cd12a552c7a79a9b965c391fb2f64a8da4912 (patch)
treef5113627f7241b7c4548e5c17c236ef6ebbf7947
parent717997bc93aab02ac868cc23ada4eabc79285b94 (diff)
downloadopen-iov-b37cd12a552c7a79a9b965c391fb2f64a8da4912.tar.gz
open-iov-b37cd12a552c7a79a9b965c391fb2f64a8da4912.zip
sema: consume stale GPFIFO entries after repeated rescue failures
Entries whose push buffer was overwritten (the rescue cannot validate any candidate page) were retried forever, rescanning RAM every 5 s and leaving the ring stuck behind them. After three real rescue failures (rate-limited attempts do not count) the entry is consumed with a 'skipping stale entry' log and the pump moves on. New skip= stat.
-rw-r--r--kernel/gsp_sema_service.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 0a4e723..930118e 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -141,6 +141,7 @@ struct svc_channel {
u32 expected_sem_payload; /* next semaphore payload we expect for this channel's tracking sem */
u32 logged_expected; /* last pool value logged (rate limit) */
unsigned long rescue_last; /* rate limit for the full-RAM rescue scan */
+ u32 rescue_fail; /* consecutive failed rescues for the entry */
};
/*
@@ -317,6 +318,7 @@ struct sema_svc {
u64 entry_log; /* per-push summary budget */
u64 ops_denied; /* work refused: implausible stream */
u64 false_trans; /* resolvable VA mapped to non-push */
+ u64 gpfifo_skipped; /* stale entries consumed */
u64 releases_seen;
u64 releases_applied;
u64 releases_missed; /* no VA->PA entry */
@@ -1463,11 +1465,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\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\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.false_trans, svc.gpfifo_skipped);
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);
@@ -3357,6 +3359,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
u8 *pb = kmalloc(len, GFP_KERNEL);
if (pb) {
+ int rescue_rc;
bool unreadable =
svc_read_va_trusted(vgpu, va,
pb, len) != 0;
@@ -3408,7 +3411,10 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
if (svc.false_trans && svc.false_trans < 8)
pr_info("sema-svc: false translation for push va=0x%llx (h=0x%x len=%u) - rescuing\n",
va, ch->h_object, len);
- if (!svc_rescue_push_page(vgpu, ch, va, len)) {
+ rescue_rc = svc_rescue_push_page(vgpu,
+ ch, va, len);
+ if (!rescue_rc) {
+ ch->rescue_fail = 0;
/* Rescue succeeded, retry the read. */
if (!svc_read_va_trusted(vgpu, va, pb,
len)) {
@@ -3438,6 +3444,29 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
kfree(pb);
break;
}
+ } else if (rescue_rc == -EAGAIN) {
+ /* Rate-limited: try again later. */
+ svc.gpfifo_nomap++;
+ kfree(pb);
+ break;
+ } else if (++ch->rescue_fail >= 3) {
+ /*
+ * The slot no longer holds this
+ * push (overwritten buffer): the
+ * rescue cannot validate any
+ * candidate. Consume the entry so
+ * the pump moves on instead of
+ * rescanning RAM every 5 s.
+ */
+ pr_info("sema-chan: skipping stale entry h=0x%x va=0x%llx len=%u after %u failed rescues\n",
+ ch->h_object, va, len,
+ ch->rescue_fail);
+ ch->rescue_fail = 0;
+ ch->last_get = (idx + 1) %
+ ch->gpfifo_entries;
+ svc.gpfifo_skipped++;
+ kfree(pb);
+ continue;
} else {
svc.gpfifo_nomap++;
kfree(pb);