diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-15 01:19:12 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-15 01:19:12 -0400 |
| commit | 3ae0688d5185305f2d9e2caa06415eab0dc0c1d0 (patch) | |
| tree | db43d2bdf0e36bb0eb58c3a23b3577ec516c367a /tools/guest-diag/guest_pin_stream.py | |
| parent | 8479659ce21bfae6639194d533ca925ba9fdd9b6 (diff) | |
| download | open-iov-3ae0688d5185305f2d9e2caa06415eab0dc0c1d0.tar.gz open-iov-3ae0688d5185305f2d9e2caa06415eab0dc0c1d0.zip | |
guest-diag: single-instance scanner start + full-re-assert backoff
r148 ran THREE guest scanners (pin_gr_stream install_and_start retried
while a partially-failed first attempt had already started one, and the
pid-file kill missed it). Each scanner re-asserted the whole CE pair set
every 2 s; with a fully fragmented pair set (descending PAs, one page per
line) that is ~2 k debugfs writes/s per scanner, and the guest hit load 19
with clients wedged spinning in userspace.
- pin_gr_stream._start_cmd: kill EVERY existing scanner first (pattern
assembled at runtime with printf so the command's own cmdline cannot
self-match), then start exactly one.
- guest_pin_stream._emit_ce_mem_delta: the full re-assert keeps its 1.5 s
cadence for the first STREAM_FULLREM_FAST_S seconds of a mem's life (the
client-switch flush race), then backs off to STREAM_FULLREM_SLOW_S (10 s)
as a safety net. Configurable via env.
Diffstat (limited to 'tools/guest-diag/guest_pin_stream.py')
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index 7d07f55..e80751a 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -458,7 +458,9 @@ def _emit_ce_mem_delta(kc, st, out, fresh_map=False): nowm = time.monotonic() full = nowm >= st.get("full_next", 0.0) if full: - st["full_next"] = nowm + KC_FULLREM_S + age = nowm - st.get("resolved_at", nowm) + st["full_next"] = nowm + (KC_FULLREM_S if age < KC_FULLREM_FAST_S + else KC_FULLREM_SLOW_S) if fresh_map: for k in range(npages): kc._pa_cache.pop(cpu + (k + off) * 0x1000, None) @@ -680,8 +682,15 @@ KC_REMAP_S = 30.0 # full re-translation sweep (catches remaps) # whole translatable pair set regardless of the delta, healing host-side # session-flush wipes (see _emit_ce_mem_delta). Must stay well under the # host's gsp_sema_ce_grace_ms (8 s) so a wiped-and-needed page is restored -# inside the hold window. -KC_FULLREM_S = 1.5 +# inside the hold window. The fast cadence applies to a mem's first +# KC_FULLREM_FAST_S seconds (the flush race lives at the client switch); +# after that the re-assert backs off to KC_FULLREM_SLOW_S - a fully +# fragmented pair set (descending PAs) emits one page per line, and 4 k +# lines every 2 s saturated a guest under multi-client load (r148: load 19, +# three scanners from an install race, clients wedged). +KC_FULLREM_S = float(os.environ.get("STREAM_FULLREM_S", "1.5")) +KC_FULLREM_FAST_S = float(os.environ.get("STREAM_FULLREM_FAST_S", "45")) +KC_FULLREM_SLOW_S = float(os.environ.get("STREAM_FULLREM_SLOW_S", "10.0")) def _chain_mems_at(kc, w): @@ -870,7 +879,8 @@ def resolve_pb_chain(kc, sem, out): gpus, cpu, off, npages = params st = {"mem": mem, "gpu": gpu, "cpu": cpu, "gpus": gpus, "page_va": cpu, "page_pa": kc.va_to_pa(cpu) or 0, - "page_off": off, "npages": npages, "last": {}} + "page_off": off, "npages": npages, "last": {}, + "resolved_at": time.monotonic()} # Fresh translation for the first sweep: the Kcore PA cache may hold # pairs from before this mem's vmap area was (re)populated. kc._pa_cache.clear() |
