summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 16:59:57 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 16:59:57 -0400
commit0f73f4e69344eab4ffebaf310ba2d937b4471ea9 (patch)
tree911e726666a7d74ec6747c8623d8bfddc7748579 /kernel
parent127d41aae5a68f07c87785193cdf17469412ba1b (diff)
downloadopen-iov-0f73f4e69344eab4ffebaf310ba2d937b4471ea9.tar.gz
open-iov-0f73f4e69344eab4ffebaf310ba2d937b4471ea9.zip
vgsp-sema r563c: the stall watchdog gates on ACTIVE withheld work, not cumulative counters
r566 evidence: the dump fired 4x with done=8929 and opdef=215/7/5 frozen while the ring was EMPTY (every channel last_get == put - the clients were waiting, no entry pending) and the forced flush had nothing to deliver: is a lifetime counter (215 holds applied/expired long ago), not proof of a current hold. A real stall has either a pending translation (svc_pending_n) or an ACTIVE opdef slot with releases recorded (e->active && e->n); the dump (and with it the self-heal arm) now requires one of those. The r564-class true stalls (active slots holding releases) still dump and still heal.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 25ae31f..d47ec08 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -25108,8 +25108,28 @@ static void svc_stall_watch_check(void)
svc_stall_watch_last = jiffies; /* re-arm the window */
if (svc_stall_watch_dumps >= SVC_STALL_WATCH_DUMPS)
return;
- if (!svc_pending_n && !svc.opdef_held)
- return; /* idle boot, not a stall */
+ /*
+ * r563c: gate on ACTIVE withheld work, not on the cumulative counters.
+ * r566 evidence: the dump fired four times with done=8929 and
+ * opdef=215/7/5 frozen - but the ring was EMPTY (every channel
+ * last_get == put: the clients were simply waiting and no entry was
+ * pending), and the forced flush had nothing to deliver. `opdef_held`
+ * is a lifetime counter (215 holds applied/expired long ago), not
+ * proof of a current hold. A real stall has either a pending
+ * translation (svc_pending_n) or an ACTIVE opdef slot with releases
+ * recorded (e->active && e->n) - only then is there something the
+ * pump is withholding.
+ */
+ {
+ bool work = svc_pending_n != 0;
+ u32 wi;
+
+ for (wi = 0; wi < SVC_OPDEF_SLOTS && !work; wi++)
+ if (svc_opdef[wi].active && svc_opdef[wi].n)
+ work = true;
+ if (!work)
+ return;
+ }
svc_stall_watch_dumps++;
svc_stall_watch_dump();
/*