diff options
| author | open-iov-agent <agent@open-iov.local> | 2026-10-09 17:48:02 -0400 |
|---|---|---|
| committer | open-iov-agent <agent@open-iov.local> | 2026-10-09 17:48:02 -0400 |
| commit | baa4a1ecd170f180381cd3a6dccd23628e6cb7c5 (patch) | |
| tree | 1a10240d320894be58dd312921689f8e1bf8bfa6 | |
| parent | 210c6b21f0348151ea9145ca3372a75df046d667 (diff) | |
| download | open-iov-baa4a1ecd170f180381cd3a6dccd23628e6cb7c5.tar.gz open-iov-baa4a1ecd170f180381cd3a6dccd23628e6cb7c5.zip | |
vgsp-sema: never seed last_get past a discovery put >= 2 (ISSUE-0002)
A fresh CE channel can legitimately reach the service's first pass with a
live put far above 1: the driver publishes the put once per submitted push
((cpu_put + 1) % entries) and clients stream pushes while the service is
still discovering the channel. r56 measured healthy sessions at put=66/134
within seconds; r54's third-session rank2 discovery read p=67, g=67 (a
LIVE put), the r48 seeding set last_get=67, and the client's first push
(entry 0) was never decoded - the channel_pool_add spin. Always start at
slot 0; a genuinely stale block is still handled by the existing put-drop
resync. Also make the CE put-snapshot diagnostic per-rank (the channel
struct iterated is a local copy, so the old per-channel stamp let the
first rank spend the whole session budget) and raise its cap for a
third-session rank2 to keep logging through a stall.
| -rw-r--r-- | kernel/gsp_sema_service.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 5fd583a..96c9064 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -4717,6 +4717,8 @@ static u64 svc_rel_va_seen; static u32 svc_rel_count; static u32 svc_dbg_streams; static u32 svc_chan_put_log; +/* ISSUE-0002 (r55): per-rank put-snapshot throttle (ch is a local copy). */ +static unsigned long svc_put_log_at[32]; /* * ISSUE-0002 (r46 diag): bounded per-session log for the CE USERD discovery * decision (svc_chan_userd). Budgets reset in svc_session_flush; 3 attempts @@ -6767,6 +6769,7 @@ static void svc_session_flush(void) svc.gpfifo_entry_log = 0; svc_dbg_streams = 0; svc_chan_put_log = 0; + memset(svc_put_log_at, 0, sizeof(svc_put_log_at)); svc_userd_dbg = 0; memset(svc_userd_dbg_ch, 0, sizeof(svc_userd_dbg_ch)); svc_userd_sweep_log = 0; @@ -7866,21 +7869,25 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, ch->userd_as = ring_ap; ch->userd_ok = true; /* - * ISSUE-0002 (r48): a PUT >= 2 at discovery can only be - * the previous session's residual state - the client - * always publishes PUT=1 for a fresh channel's first - * push and waits for its release before a second. Seed - * last_get past the residual entries so the pump does - * not consume stale slots and desync from the guest's - * counter reset (r48: rank0 accepted PUT=134, the pump - * ran 34 stale entries, then the guest reset PUT=1 and - * the pump wrapped; the live first push was never - * processed). The pump detects the reset as a PUT drop - * and resyncs last_get to slot 0. + * ISSUE-0002 (r55): a PUT >= 2 at discovery is NOT + * necessarily the previous session's residual state. + * UVM publishes the put once per submitted push + * (host_hal->write_gpu_put stores + * (cpu_put + 1) % entries), and a client that streams + * pushes while the service is still discovering the + * channel leaves a LIVE put far above 1 (r56: a healthy + * session's CE puts reached 66/134 within seconds; r54's + * third-session rank2 discovery read p=67, g=67). The + * r48 seeding (last_get = p) then skipped those LIVE + * entries and the client's first push (entry 0) was + * never decoded - the channel_pool_add stall. Always + * start at slot 0; a genuinely stale block is still + * handled: the fresh channel's first publish drops the + * put below the stale put_prev and the pump's drop + * resync rewinds last_get to slot 0. */ - ch->userd_wait_fresh = p >= 2; - if (ch->userd_wait_fresh) - ch->last_get = p; + ch->userd_wait_fresh = p >= 1; + ch->last_get = 0; *put = p; *get = g; if (ch->ce_index < 32) @@ -12521,18 +12528,23 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) } /* - * ISSUE-0002 diag: per-second put snapshots for CE channels, - * bounded per session. Names whether a re-registered session's - * GP_PUT advances at all (the pump's view of the second - * client's submissions). + * ISSUE-0002 diag: put snapshots for CE channels, bounded per + * session. The throttle is indexed by rank (the channel struct + * iterated here is a local copy, so a per-channel stamp never + * persisted and the first channel's burst spent the whole + * budget - r54 had no rank2 line at all). Cap raised to 160 so + * a third-session rank2 keeps logging through its stall. */ - if (gsp_sema_dbg && ch->engine_type && svc_chan_put_log < 48 && - time_after(jiffies, ch->put_log_at)) { - ch->put_log_at = jiffies + HZ; + if (gsp_sema_dbg && ch->engine_type && ch->ce_index < 32 && + svc_chan_put_log < 160 && + time_after(jiffies, svc_put_log_at[ch->ce_index])) { + svc_put_log_at[ch->ce_index] = jiffies + HZ; svc_chan_put_log++; - pr_info("sema-put: h=0x%x uok=%d upa=0x%llx uas=%u put=%u get=%u last=%u\n", - ch->h_object, ch->userd_ok, ch->userd_pa, - ch->userd_as, put, get, (u32)ch->last_get); + pr_info("sema-put: h=0x%x rank=%u uok=%d upa=0x%llx uas=%u put=%u get=%u last=%u prev=%u fresh=%d\n", + ch->h_object, ch->ce_index, ch->userd_ok, + ch->userd_pa, ch->userd_as, put, get, + (u32)ch->last_get, ch->put_prev, + ch->userd_wait_fresh ? 1 : 0); } /* |
