diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 06:01:06 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 06:01:06 -0400 |
| commit | b37cd12a552c7a79a9b965c391fb2f64a8da4912 (patch) | |
| tree | f5113627f7241b7c4548e5c17c236ef6ebbf7947 /kernel | |
| parent | 717997bc93aab02ac868cc23ada4eabc79285b94 (diff) | |
| download | open-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.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 35 |
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); |
