diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/guest-diag/guest_pin_stream.py | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py index c0cf485..97c68f2 100644 --- a/tools/guest-diag/guest_pin_stream.py +++ b/tools/guest-diag/guest_pin_stream.py @@ -807,6 +807,38 @@ def resolve_channel_pins(kc, ch, out): +def _read_trace_snapshot(max_bytes=1 << 20, budget=0.5): + """Best-effort non-blocking read of the trace ring file. + + Spawning `tail` here left uninterruptible D-state processes when the + seq_file read blocked under load (observed r127: dozens of stuck tails, + load 26); a direct os.read with O_NONBLOCK returns whatever is ready and + never accumulates processes. + """ + try: + fd = os.open(TRACE, os.O_RDONLY | os.O_NONBLOCK) + except OSError: + return b"" + chunks = [] + got = 0 + t0 = time.time() + try: + while got < (8 << 20) and time.time() - t0 < budget: + try: + d = os.read(fd, 262144) + except BlockingIOError: + break + except OSError: + break + if not d: + break + chunks.append(d) + got += len(d) + finally: + os.close(fd) + return b"".join(chunks)[-max_bytes:] + + def seed_events_from_trace(seen_sems, seen_pbs, seen_chs): """One-shot tail scan of the trace ring after a pid switch / start. @@ -821,8 +853,7 @@ def seed_events_from_trace(seen_sems, seen_pbs, seen_chs): (the mem candidates are scored and deferred). """ try: - out = subprocess.run(["tail", "-c", "1048576", TRACE], - capture_output=True, timeout=10).stdout + out = _read_trace_snapshot() except Exception: return 0 n = 0 |
