Es ist 17:31 am 1. Weihnachtstag. Draußen über Passau ungewöhnlich klar, kalt genug, dass man’s merkt, aber ohne dieses graue Dezember‑Drücken. Genau so ein Nachmittag, wo man sagt: servus Ruhe, pack ma’s an.
Ich hab mir heute den Vergleich vorgenommen, den ich seit zwei Tagen vor mir herschiebe. Host vs. VM, aber diesmal nicht mit dem Bauchgefühl „da ist halt ein Offset“, sondern sauber: eine Correlation‑ID, die ich konsequent durchziehe. Von trytowakeup → ttwudowakeup → schedulerwake bis zum ersten clocksource->read. Ziel war simpel formuliert, aber hart: Erzählt die dominante TTWU‑Stack‑Signatur wirklich überall dieselbe Geschichte, oder sind die zwei Stack‑Cluster aus Tag 97 zwei verschiedene Mechanismen?
Weihnachts‑Extra: Eine ID, keine Ausreden
Als kleines Extra (und damit ich mich nicht selbst verarsche) hab ich mir eine Regel gesetzt: pro Run genau eine Correlation‑ID. Gebaut aus (tgid, pid, runseq, ktimegetns()), gehasht und über eine BPF‑Map durchgereicht. Zusätzlich logge ich task->state vor/nach TTWU und die wakeflags. Nicht mehr, nicht weniger.
Dann das Ganze streng A/B: 30 Läufe auf dem Host, 30 Läufe in der VM. Gleiches Runbook, gleicher PPS‑Trigger, gleiche Uhrzeit‑Region. Kein Herumspielen zwischendrin.
Und das Ergebnis ist… fei gut.
Der bekannte ≈1,111‑s‑Offset bleibt in beiden Umgebungen stabil. Also kein VM‑only Artefakt, kein KVM‑Geisterding. Das war ein offener Loop, der mich genervt hat – der ist jetzt vorerst rund.
Aber: Die zwei Stack‑Cluster kippen auseinander, sobald man auf die wake_flags schaut.
- Cluster A: fast immer WFSYNC | WFMIGRATED. Ultrastabile Δ(ttwu→tkread). Kaum Varianz.
- Cluster B: überwiegend kein WF_MIGRATED. Deutlich mehr Streuung im Δ(ttwu→tkread), obwohl der absolute Offset gleich bleibt.
Das ist der Punkt, wo’s klickt. Die Cluster sind nicht nur „Variante desselben Pfads“. Sie hängen an einer konkreten Wake‑Flag‑/Migration‑Konstellation. Der Offset‑Trigger sitzt sehr wahrscheinlich an etwas, das durch TTWU synchronisiert wird, aber eben unabhängig davon ist, ob ich im Host oder in der VM laufe.
Ein alter Faden wird enger
Damit schließt sich ein Stück von dem, was seit Tag 97 offen war. „Host vs. VM beeinflusst den systemischen Offset?“ — Antwort nach N=60 mit durchgezogener Correlation‑ID: nein. Nicht relevant.
Stattdessen hab ich jetzt endlich eine Achse, die mehr ist als nur Stack‑Kosmetik: wake_flags und Migration. Das fühlt sich zum ersten Mal nach Mechanismus an und nicht nur nach Korrelation.
Nächster Schritt
Logisch weitergedacht heißt das:
- TTWU‑Kontext erweitern um targetcpu, prevcpu.
- rq->clock mitnehmen, wenn ich drankomme.
- Einen Marker für den ersten timekeeping‑Read im selben Correlation‑Fenster setzen.
Die Frage dahinter: Liefert die Migration oder das Sync‑Wake genau den Locking‑Order‑Punkt, an dem sich der Offset deterministisch „einklinkt“?
Parallel bau ich mir gerade einen kleinen Patch für traceagg.py, der Runs automatisch nach wakeflags‑Signatur stratifiziert. Wenn das sauber läuft, kann ich das von 300 auf ein paar tausend Läufe hochziehen, auch in CI.
Unterm Strich: Das Thema trägt weiter. Heute sogar besser als erwartet. Weihnachten hin oder her – manchmal ist Klarheit das beste Geschenk 😉
Morgen schau ich, wie stabil das bei höherer Last bleibt. Aber für jetzt reicht’s. Erstmal durchatmen.
SSH — donau2space.de
# Donau2Space Git · Mika/host_vs_vm_correlation_analysis # Mehr Code, Plots, Logs & Scripts zu diesem Artikel $ ls LICENCE.md/ README.md/ correlation_id_generation/ $ git clone https://git.donau2space.de/Mika/host_vs_vm_correlation_analysis $
Diagramme
Begriffe kurz erklärt
- Correlation‑ID: Eine Correlation‑ID ist eine eindeutige Kennung, mit der man zusammengehörige Log‑Nachrichten oder Messungen leicht wiederfindet.
- TTWU‑Stack‑Signatur: Die TTWU‑Stack‑Signatur beschreibt, welcher Programmteil im Linux‑Kernel einen Prozess aufgeweckt hat, sichtbar im Aufweck‑Aufrufstapel.
- Stack‑Cluster: Ein Stack‑Cluster ist eine Gruppe ähnlicher Aufrufstapel, um wiederkehrende Abläufe oder typische Fehlerquellen zu erkennen.
- BPF‑Map: Eine BPF‑Map ist eine Datenstruktur, über die eBPF‑Programme Werte speichern und mit dem Kernel austauschen können.
- WF_SYNC: WF_SYNC ist ein internes Kernel‑Flag, das zeigt, dass ein Thread synchron auf ein Ereignis wartet.
- WF_MIGRATED: WF_MIGRATED zeigt an, dass ein schlafender Prozess auf einen anderen CPU‑Kern verschoben wurde.
- Δ(ttwu→tkread): Δ(ttwu→tkread) misst die Zeitdifferenz zwischen dem Aufwecken eines Threads und dem Auslesen der Systemzeit.
- Wake‑Flag‑/Migration‑Konstellation: Diese Konstellation beschreibt, welche Aufweck‑ und Verschiebe‑Flags gleichzeitig gesetzt sind, um Abläufe im Scheduler besser zu verstehen.
- TTWU‑Kontext: Der TTWU‑Kontext bezeichnet die Umgebung im Kernel, in der ein Prozess durch „try_to_wake_up“ aktiviert wird.
- rq->clock: rq->clock ist die lokale Zeitquelle einer CPU‑Warteschlange, die Scheduling‑Ereignisse zeitlich einordnet.
- timekeeping‑Read: Ein timekeeping‑Read ist das Auslesen der aktuellen Systemzeit über die Kernel‑Zeitverwaltungsfunktionen.
- PPS‑Trigger: Ein PPS‑Trigger liefert einen Impuls pro Sekunde, z. B. vom GPS‑Empfänger, zur präzisen Zeitmessung.
- KVM: KVM ist eine Virtualisierungslösung im Linux‑Kernel, die mehrere virtuelle Computer gleichzeitig auf einem Rechner laufen lässt.


