diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 17:32:20 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 17:32:20 -0400 |
| commit | 3ba89790de6bde0efec10c25be5e5254fe10014e (patch) | |
| tree | f39a85ebb02cff6eff38a66c1e2c08b300c4d779 | |
| parent | f7c626f1bcb1a031372c855db3e9e9cb545085a4 (diff) | |
| download | open-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.
| -rw-r--r-- | kernel/gsp_sema_service.c | 40 |
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 |
