diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-24 07:28:30 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-24 07:28:30 -0400 |
| commit | d1e302e6986194053f95d619b816f0a435e70e24 (patch) | |
| tree | 8f56bc6093204e80013f367125201e26464390f1 | |
| parent | d74fcf75e22d9f94ecbc49772d9770b7b4999f36 (diff) | |
| download | open-iov-d1e302e6986194053f95d619b816f0a435e70e24.tar.gz open-iov-d1e302e6986194053f95d619b816f0a435e70e24.zip | |
vgsp-sema r610: a replay pass must not re-mark a copy entry as operand-pending - the held-chain livelock
The fail4 r302 block marks a denied device-destination copy op_tr_pending so
the m163/opdef hold retries it. It fires on EVERY decode pass with
allow=false - including a REPLAY pass, which is the pump re-walking an entry
whose ops were already recorded complete for this identity (entry_replay =
same && slot_ops_complete). The re-mark therefore un-completes a slot whose
copy HAS run: the next pass is fresh, re-executes the op, the next pin-batch
rewind re-marks it again - a replay/fresh/replay cycle that re-arms a 3 s
opdef hold every round and stalls the whole copy channel behind it.
Measured: 100% of the op_tr_pending marks in the r604-r609 boots came from
replay passes (27/27 in r609; 71/71 in r606, whose captured held chain
idx=90/92 is this shape; 72/72 in r608). In the r609 boot the d_b H2D entry
(idx=94) was re-marked and re-run every ~0.3 s from 368841 while the vadd
launch waited on it; the launch then hit the r586 fail-closed cap at 15 s
and the engine never wrote (VADD bad=32767 csum=0).
r308's rationale for the replay re-mark (pre-r595 the eng==0 copy channel's
fresh passes never admitted ops, so the re-mark was the only retry hatch) no
longer holds: r595's cap_trust admission runs a plausible copy on its fresh
pass, and a genuinely failed copy keeps its slot incomplete via op_owed / the
svc_run_ops rc!=0 pending rule. The whole denied accounting block (dstpend
note, staging re-snapshot, pending mark, hold) is now skipped on replay; a
fresh (non-replay) denied pass marks exactly as before.
| -rw-r--r-- | kernel/gsp_sema_service.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index cb9d731..fa11f68 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -11410,8 +11410,34 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, * soon as the trust (or the operand translation) * arrives; the bounded SVC_OPDEF_HOLD_MS expiry keeps * the pre-existing skip as the last resort. + * + * r610: a REPLAY pass must be exempt. A replay is the + * pump re-walking an entry whose ops were already + * recorded complete for this identity (entry_replay = + * same && slot_ops_complete): re-marking it as pending + * re-arms a 3 s opdef hold for a copy that HAS run, + * and the fresh pass that follows re-executes the op - + * a replay/fresh/replay cycle (r609 boot, idx=94: the + * d_b H2D re-marked and re-run every ~0.3 s from + * 368841 while the vadd launch waited; the r606 + * captured held chain is the same shape). Measured + * r604-r609: 100% of op_tr_pending marks (27/27, + * 71/71, 72/72) came from replay passes of already- + * executed copies - each one stalled the whole copy + * channel behind it, which is the held-chain class. + * The r308 rationale (pre-r595 the eng==0 copy + * channel's fresh passes never admitted ops, so the + * replay re-mark WAS the retry hatch) no longer + * applies: r595's cap_trust admission runs a plausible + * copy on its fresh pass, and a genuinely failed copy + * keeps its slot incomplete through op_owed / the + * rc!=0 pending rule. The whole accounting block is + * skipped on replay: no dstpend note (the write ran), + * no staging re-snapshot, no hold. A fresh + * (non-replay) denied pass marks pending exactly as + * before. */ - if (!allow_ops && trusted && + if (!allow_ops && trusted && !replay && !ch->engine_type && transfer != 0 && st.line_length && st.have_out && st.have_in && !DMA_REMAP_ENABLE(dma) && |
