diff options
Diffstat (limited to 'tools/guest-diag/pin_gr_stream.py')
| -rw-r--r-- | tools/guest-diag/pin_gr_stream.py | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/tools/guest-diag/pin_gr_stream.py b/tools/guest-diag/pin_gr_stream.py index 2f78f2a..6ba51ee 100644 --- a/tools/guest-diag/pin_gr_stream.py +++ b/tools/guest-diag/pin_gr_stream.py @@ -328,10 +328,11 @@ def main(): chunk = conn.recv(1 << 20) except socket.timeout: if runs: + novel = _novel_pages(runs, seen) pages = _flush(runs, seen) pin_total += pages pins_since_client += pages - if pages: + if novel: _activity() runs = [] _maybe_reassert_request(seen) @@ -433,12 +434,18 @@ def main(): int(m.group(2), 16), int(m.group(3)) if m.group(3) else 1)) if runs: + novel = _novel_pages(runs, seen) pages = _flush(runs, seen) pin_total += pages pins_since_client += pages - if pages: + if novel: _activity() runs = [] + # Poll the semfix re-assert request on every recv cycle, not + # only on recv-timeouts: sustained scanner traffic starves the + # timeout branch, so the request fired post-mortem in r203 + # (119 s late, `seen` already cleared by #nopid). + _maybe_reassert_request(seen) except Exception as e: # A transient error on one connection must not kill the process: # log it, drop the connection and go back to accept(). @@ -482,6 +489,17 @@ def _coalesce_seen(seen): return runs +def _novel_pages(runs, seen): + """Count pages in runs whose translation is new or changed. + + Progress accounting for the stall watchdog: the guest re-streams the CE + window and UVM pool every couple of seconds even when nothing moves, so a + pure repeat of an already-known pair must not count as pin activity + (r203: those repeats masked the watchdog through every hang).""" + return sum(1 for va, pa, n in runs for i in range(n) + if seen.get(va + i * 0x1000) != pa + i * 0x1000) + + def _flush(runs, seen, full=False): """Inject run lines (one batched sudo pass), return number of pages pinned. |
