summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtools/guest-diag/semfix_uvmt.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/tools/guest-diag/semfix_uvmt.py b/tools/guest-diag/semfix_uvmt.py
index b9f3ac9..636e1f4 100755
--- a/tools/guest-diag/semfix_uvmt.py
+++ b/tools/guest-diag/semfix_uvmt.py
@@ -69,6 +69,16 @@ class Stream:
self.pbs = []
self.new_pbs = []
+ def reset(self):
+ """Forget everything learned about the previous client. A new client
+ allocates its own channel pools; keeping the old sems/seen-pin marks
+ makes the watcher chase stale kernel pointers and pin the previous
+ client's (freed) pool pages - the stale-translation trap."""
+ self.sems = []
+ self.pbs = []
+ self.pids = []
+ self.new_pbs = []
+
def poll(self):
try:
with open(self.path) as f:
@@ -290,6 +300,17 @@ def main():
log("stream: new uvmt sem 0x%x" % s)
for p in new_pids:
log("stream: client pid %d" % p)
+ if last_pid is not None and p != last_pid:
+ stream.reset()
+ known_sems.clear()
+ seen_sem_pin.clear()
+ last_state.clear()
+ last_seen_t.clear()
+ pinned_ranges.clear()
+ seen_ch.clear()
+ seen_pb.clear()
+ counter_pids.clear()
+ log("semfix: new client pid %d - reset per-client pin state" % p)
last_pid = p
for pb in getattr(stream, "new_pbs", []):
log("stream: new pushbuffer 0x%x" % pb)