summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-28 11:13:47 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-28 11:13:47 -0400
commit3a6b7ca87129a995f0b3d7ddb0ea7c9893d430c0 (patch)
tree2545f6751783aecb322d47e8be0bb100bce4a868
parent30f3363286f541198da174cc7508706484dbbee6 (diff)
downloadopen-iov-3a6b7ca87129a995f0b3d7ddb0ea7c9893d430c0.tar.gz
open-iov-3a6b7ca87129a995f0b3d7ddb0ea7c9893d430c0.zip
sema: clamp the pin-rewind at ring start - never wrap below zero
The rewind used entries - (N - get) for get < N, which for an empty ring (get=0, put=0) jumped last_get to entries-8, so the pump read ring slots the producer had never reached and could execute stale/garbage entries. Replay only recently consumed slots, clamped at 0.
-rw-r--r--kernel/gsp_sema_service.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 020023a..ba26b3d 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -3486,9 +3486,14 @@ static void svc_handle_map_add(void)
if (!ch->valid || !ch->gpfifo_entries)
continue;
+ /*
+ * Clamp the rewind at 0: wrapping below zero (get=0 -> entries
+ * - N) makes the pump read ring slots past the producer that
+ * hold stale entries, so replay only recently consumed slots
+ * or from the start of the ring, never around the wrap.
+ */
get = ch->last_get;
- ch->last_get = (get >= SVC_PIN_REWIND) ? get - SVC_PIN_REWIND :
- ch->gpfifo_entries - (SVC_PIN_REWIND - get);
+ ch->last_get = (get >= SVC_PIN_REWIND) ? get - SVC_PIN_REWIND : 0;
}
spin_unlock_irqrestore(&svc.chan_lock, flags);