summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-12 05:09:17 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-12 05:09:17 -0400
commit71489ff832717592f2d4a23fea29d69fee5bee42 (patch)
treeceb697d4bcaef1865a3cd9ea78e0ef101a87d79e /kernel/gsp_sema_service.c
parent3e677f506db6d247a19b2b3df28ff86b6f763b51 (diff)
downloadopen-iov-71489ff832717592f2d4a23fea29d69fee5bee42.tar.gz
open-iov-71489ff832717592f2d4a23fea29d69fee5bee42.zip
vgsp-sema: re-arm ring/push-buffer discovery latches on channel registration; scanner streams anonymous high-VA buffers
Second-client wedge fix: a new GSP session re-registers the same channel handles/ranks, but the per-rank one-shot ring/push-buffer discovery latches stayed set from the previous session, so the new session's ring was never re-autopinned (ring_auto=0 pb=0/0, nomap growing) and the guest spun in its channel-creation wait. svc_chan_rearm_rank() clears the latches on every channel registration; all post-fix cycles launch the second client. Scanner: guest_pin_stream.py now streams the client's anonymous high-VA mappings (cudaMalloc buffers were skipped by the old len(parts)<6 check), so the host can learn their pages. Diagnostics: PT-window lines, per-window first words, post-OK qmdwin w48..59. Remaining: the fill-time svc_ipin_lookup miss for the second client's a/b/c pins (they exist in the pin log but are not seen at fill time) - next session.
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 3c47ed3..561ebf0 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -928,6 +928,34 @@ static int svc_write_ap(struct nv_vgpu_device *vgpu, u64 addr, u32 aperture,
static bool svc_gr_content_rearm;
/*
+ * m148 (second-client wedge): re-arm the per-rank one-shot ring/push-buffer
+ * latches for a (re-)registered channel. The guest driver rebuilds the GSP
+ * session for every client context and RM reuses the same object handles and
+ * channel ranks across sessions. The ISSUE-0002 session flush only runs on
+ * the last-channel-closed transition, so a second session that re-registers
+ * the same handles while the first session's entries are still present (or
+ * before the deferred flush executes) inherits the previous session's latch
+ * bits. The CE/GR ring autopin and the push-buffer pairing then never re-run,
+ * the new session's ring stays untranslated (svc_lookup fails for its GPFIFO
+ * VA), the pump counts the entries as nomap and the guest spins forever in
+ * uvm_tracker_wait_for_entry waiting for its channel-creation push release -
+ * the second-client wedge. Both autopin paths and the pairing are
+ * content-validated (entry0 must parse; a discovered base must carry this
+ * channel's slot), so re-arming is safe and idempotent within a session.
+ */
+static void svc_chan_rearm_rank(struct svc_channel *ch)
+{
+ if (!ch || !ch->valid)
+ return;
+ if (ch->engine_type) {
+ clear_bit(ch->ce_index, &svc_ring_done);
+ clear_bit(ch->ce_index, &svc_pb_done);
+ } else {
+ clear_bit(ch->gr_index, &svc_gr_ring_done);
+ }
+}
+
+/*
* Register a guest channel. Called from the GSP-RM emulation when the guest
* driver allocates a channel (the allocation carries the GPFIFO GPU VA, its
* entry count and the guest-physical USERD/instance blocks), and dropped when
@@ -1050,6 +1078,13 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc)
spin_unlock_irqrestore(&svc.chan_lock, flags);
if (ch) {
+ /*
+ * m148: force the ring/push-buffer discovery latches for this
+ * rank to re-run for the (possibly new) session, so the new
+ * ring is translated from its own content instead of inheriting
+ * the previous session's one-shot state (second-client wedge).
+ */
+ svc_chan_rearm_rank(ch);
svc.last_chan_reg = jiffies;
pr_info("sema-svc: channel 0x%x registered gpfifo=0x%llx entries=%u userd=0x%llx eng=%u cid=%u notif=0x%llx\n",
desc->h_object, desc->gpfifo_va, desc->gpfifo_entries,
@@ -1063,7 +1098,6 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc)
/* P6b wave-1.5 hold state is defined with the forwarding section below. */
static void svc_fwd_hold_abort(u32 h_object);
-
/*
* P6b wave-2 inline software fallback for a withheld (skipped) candidate;
* defined with the forwarding section below. Service-thread only.