summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 17:32:20 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 17:32:20 -0400
commit3ba89790de6bde0efec10c25be5e5254fe10014e (patch)
treef39a85ebb02cff6eff38a66c1e2c08b300c4d779 /kernel
parentf7c626f1bcb1a031372c855db3e9e9cb545085a4 (diff)
downloadopen-iov-3ba89790de6bde0efec10c25be5e5254fe10014e.tar.gz
open-iov-3ba89790de6bde0efec10c25be5e5254fe10014e.zip
vgsp-sema r566: note a held entry's unexecuted device-dst copies for the launch guard
Root cause (r567/r568, deterministic): the mail client's b H2D COPY op was COLLECTED but never attempted while its entry was held for another operand; the VADD launch's copy-in ran 0.6 s BEFORE the copy executed, so the engine read b = 0 and computed c = a + 0 (the readback page held a's values {0.0,0.5,1.0,1.5} vs the correct {0.0,0.75,1.5,2.25}). The r541 guard only saw copies that FAILED with -ENOENT (svc_dstpend_note at the failure site), so a merely PENDING copy was invisible to it. svc_dstpend_note_ops() runs after each svc_run_ops() call in svc_decode_stream whenever svc.op_tr_pending is set: every collected device-dst copy whose per-op done bit is not set (i.e. did not execute this pass or earlier) gets its destination noted. The launch guard then defers until the copy runs (the copy's success path clears the record), bounded by the existing dstpend TTL + busy-defer + 15 s cap machinery.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index e96a7b6..80c858b 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -7950,6 +7950,36 @@ static void svc_dstpend_note(u64 va)
svc_dstpend[i].since = jiffies;
}
+/*
+ * r566: note the destinations of every COLLECTED device-dst copy that did
+ * not execute this pass, whenever the entry is being held (op_tr_pending).
+ * The r541 launch guard could only see copies that FAILED with -ENOENT
+ * (svc_dstpend_note at the failure site); the r568 mail failure is the
+ * missing case: the b H2D's COPY op was collected but never attempted while
+ * its entry was held for another operand, the launch's copy-in ran 0.6 s
+ * before the copy executed, and the engine computed c = a + 0 (the
+ * readback page held a's values). With the destination noted, the launch
+ * guard defers until the copy runs (its success path clears the record),
+ * bounded by the same dstpend TTL + busy-defer machinery as every other
+ * guard.
+ */
+static void svc_dstpend_note_ops(struct svc_memset_op *ops, u32 n, u32 base,
+ u64 *ops_done)
+{
+ u32 i;
+
+ for (i = 0; i < n; i++) {
+ struct svc_memset_op *m = &ops[i];
+ u32 seq = base + i;
+
+ if (m->type != 1 || m->phys || m->dst < SVC_VAS_FLOOR)
+ continue;
+ if (ops_done && seq < 64 && ((*ops_done >> seq) & 1))
+ continue; /* executed (this pass or earlier) */
+ svc_dstpend_note(m->dst);
+ }
+}
+
static void svc_dstpend_clear(u64 va)
{
u64 page = va & ~(u64)(SEMA_PAGE_SIZE - 1);
@@ -10334,6 +10364,12 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
svc.ring_ops++;
ops_runs++;
}
+ /* r566: a held entry's unexecuted device-dst
+ * copies must be visible to the launch guard. */
+ if (svc.op_tr_pending)
+ svc_dstpend_note_ops(ops, n_ops,
+ ops_seq - n_ops,
+ ops_done);
n_ops = 0;
/*
* A release to a GR completion counter must go
@@ -10535,6 +10571,10 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf,
svc.ring_ops++;
ops_runs++;
}
+ if (svc.op_tr_pending)
+ svc_dstpend_note_ops(ops, n_ops,
+ ops_seq - n_ops,
+ ops_done);
n_ops = 0;
/*
* ISSUE-0002 (r62/r65): a captured