diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 12:24:19 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 12:24:19 -0400 |
| commit | d45db82ea2656f536f08d4c80da406be81dea21f (patch) | |
| tree | 8275687beb77cb33241eefd57fbc5732ca838266 /kernel | |
| parent | ce499542ca2560a25ad1d94890838d741dba7238 (diff) | |
| download | open-iov-d45db82ea2656f536f08d4c80da406be81dea21f.tar.gz open-iov-d45db82ea2656f536f08d4c80da406be81dea21f.zip | |
vgsp-sema r549: cap the dead-operand walk at 3 s per entry (opdef hold + opfail window)
r548 evidence (matmul, reused channel handle 0x5c000059 after the previous
client exited): the new client's init sequence carries ~65 small
device-destination ops whose operands no resolver covers (memcopy/memset
rc=-2, SVC_VAS_FLOOR destinations like 0x2000c0100). Each one armed the
opdef hold, expired after exactly 10 s (OPDEF-EXPIRED idx 7..18 at ~10.5 s
spacing) and only then released the counter increment the client waits on:
the pump walked one entry per 10 s while the client spun at 100 % CPU
(12+ min, battery timeout).
The two bounds were both 10000 ms. Ops that DO resolve show 0.5-2 s pin
latency (SVC_OPDEF_HOLD_MS comment), so 3000 ms keeps the m163 guarantee
(a failed device copy still gets its retry once the pins land) and the
op-failure latch now fires on the first 3 s retry instead of a second
10 s window. Both are pure bounds - no path loses its retry.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index bb52358..3da8e54 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -7834,11 +7834,21 @@ static struct svc_wait_hold *svc_wait_hold_get(u32 h, bool create) */ #define SVC_OPFAIL_MAX 32 /* - * r507a: the op-failure window rides the opdef hold bound (10000 ms, - * SVC_OPDEF_HOLD_MS defined further down). Keep the literal here so the - * latch (used by svc_run_ops) precedes that define. - */ -#define SVC_OPFAIL_WINDOW_MS 10000u + * r507a: the op-failure window rides the opdef hold bound (SVC_OPDEF_HOLD_MS + * defined further down). Keep the literal here so the latch (used by + * svc_run_ops) precedes that define. + * + * r549: 10000 -> 3000. The window is the SECOND wait an unresolvable op + * costs: fail #1 arms this record, the entry is held for the opdef bound, + * the retry's fail #2 latches the op out of the hold. r548 evidence: a + * client whose init sequence carries ~65 device-dst ops with destinations + * no resolver covers walked one entry per 10 s (OPDEF-EXPIRED every + * 10.5 s, idx 7 -> 18) - the client spun at 100 % CPU for 10+ minutes and + * the battery timed out. Ops that DO resolve show 0.5-2 s pin latency, so + * 3 s keeps the m163 protection and cuts the dead-op cost to ~3 s per + * distinct destination. + */ +#define SVC_OPFAIL_WINDOW_MS 3000u static struct { u64 va; unsigned long since; @@ -17122,8 +17132,17 @@ static void svc_fwd_rel_apply_all(struct nv_vgpu_device *vgpu, * Bounded hold: comfortably above the observed ~1 s pin latency and well * inside the 25 s CE grace, so a genuinely dead operand delays its * channel by this much and then falls back to the old skip-and-release. - */ -#define SVC_OPDEF_HOLD_MS 10000u + * + * r549: 10000 -> 3000. r548 evidence: a reused channel handle whose new + * client submits ~65 init entries with device-dst ops no resolver covers + * walked one entry per 10 s (the journal shows OPDEF-EXPIRED exactly + * every 10.5 s, idx 7 -> 18) while the client spun at 100 % CPU - the + * release set the client waits on advances one entry per hold, so the + * bound is the stall multiplier. Ops that do resolve land in 0.5-2 s; + * 3 s keeps the m163 guarantee (a failed device copy is still retried + * once after its pins arrive) and caps the dead-op walk 3.3x shorter. + */ +#define SVC_OPDEF_HOLD_MS 3000u struct svc_opdef_ent { bool active; |
