summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/guest-diag/guest_pin_stream.py35
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