Alles. WITNESS ist ein Deadlock-Detektor. Simpel gesagt schreibt er einen Graph, der alle gerade gehaltenen Locks im System beinhaltet. Jeder Lock ist ein Knoten, die Beziehungen untereinander werden durch die Kanten symbolisiert. Wenn es in dem Graphen einen Zyklus (für die Nichtinformatiker: Eine Möglichkeit im Kreis zu laufen) gibt, ist das ein potentieller Deadlock. Damit das funktioniert, muss jedes Mal wenn ein Lock angefordert oder wieder freigegeben wird, dieser Lock in Form eines neuen Knoten in den Graphen eingefügt werden und man muss prüfen, ob der Graph noch zyklenfrei ist. Das ist aber, wie man sich denken kann, extrem teuer. Pro Sekunde werden im Kernel - durch den inneren Kern selbst, durch das VM, das VFS, GEOM, den Netzwerkstack, UFS, ZFS, Treiber und vielem mehr zehntausende Locks angefordert und wieder freigegeben. Statt wenigen CPU-Zyklen dauert es mit Witness jedes mal sehr lange und schluckt CPU-Last ohne Ende. Oder anders gesagt: Baust du einen Kernel mit Witness, sinkt deine verfügbare CPU-Leistung deutlich. Egal was das System genau macht. Daher steht in -CURRENT in /usr/src/UPDATING auch der Hinweis "If you think that FreeBSD 9 ist slow...", da dort WITNESS immer eingeschaltet ist.
Noch drei Hinweise zu Witness:
- Witness erkennt fast alle Deadlock, aber es gibt einige Randfälle, die er nicht greifen kann. Erkennt er nichts, kannst du nur 99% sicher sein, dass du keinen Deadlock hast. Nicht zu 100%.
- Ein erkannter Deadlock bedeutet nicht "hier wäre das System verklemmt". Es bedeutet nur, dass eine Verklemmung möglich wäre, d.h. die Voraussetzungen gegeben sind. Eintreten muss sie noch lange nicht, was das Erkennen und Beseitigen von Verklemmungen ohne Mechanismus zur Erkennung sehr schwer macht.
- Witness hat eine gewisse Neigung zu Falscherkennungen. Es gibt im Kernel einige Stellen, an denen Witness einen Deadlock erkennt, der aber niemals eintreten kann. Eine der bekanntesten dieser Stellen ist eine Falscherkennung in UFS, die du fast sicher sehen wirst, falls du es nutzt.
Wenn Witness einen Deadlock findet, schreibt er dir "lock order reversal" auf die Standardkonsole und damit auch in /var/log/messages. "lock order reversal" oder kurz LOR ist nichts anderes als ein Deadlock. Darauf folgt eine Ausgabe der Locks, die gerade gehalten wurden, also was mit wem verklemmt. Wenn Debugsymbole vorhanden sind (also ein kernel.debug gestartet wurde), gibt er auch die genauen Zeilen aus, wo die Locks angefordert wurden. Diese Informationen solltest du mit der FreeBSD LOR Page abgleichen:
http://sources.zabbadoz.net/freebsd/lor.html Das kann helfen zu entscheiden, ob das Problem bekannt ist. Dann kannst du entscheiden, was du weiter machen willst. Bei den dort aufgeführten LOR gibt es in der Detailansicht auch einen Knopf weitere Informationen beizusteuern.
Ach ja: Bei den wirklich kritischen Deadlocks springt FreeBSD dann in die Panic um zu verhindern, dass das System verklemmt und du nichts mehr machen kannst. Wenn du nicht am Debugger-Prompt landen willst (sofern der Debugger aktiv ist), konfiguriere am Besten Kerneldumps. Dann schmiert er ab, dumpt, startet neu und du hast den Dump zur weiteren Analyse. Löst auch das Problem, dass du einen manuellen Reset machen musst.
Das Ding auch ne Manpage: witness(4)