Ich habe einen 2.6.35 PREEMPT-Kernel, der auf einem ARMv7-Prozessor mit mittlerer Geschwindigkeit ausgeführt wird. Ungefähr alle 100 - 125 Sekunden führt etwas dazu, dass der Kernel einige Audio-Treiber nicht schnell genug verarbeitet, um Unterläufe zu vermeiden. Der Hold-up liegt im Allgemeinen im Bereich von 15 bis 30 ms, kann jedoch sehr viel länger sein. Es ist nicht klar, ob der Hold-up vollständig im Kernel ist oder sich auf die Planung eines Benutzerprozesses bezieht, der mit Echtzeitpriorität ausgeführt wird (SCHED_RR, 2).
Ich vermute, dass es einen (mindestens einen) Treiber gibt, der mit Preempt nicht gut spielt.
Einige Strace-Ausgaben des Benutzerprozesses veranschaulichen einen Aspekt sowohl des normalen als auch des abnormalen Verhaltens, obwohl ich nicht sicher bin, wie die verschiedenen Zeitberichte zu interpretieren sind.
Normalfall:
0,000518 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3415) = 1 0.010202 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 0,000585 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3404) = 1 0,000302 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3404) = 1 0.010706 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3393) = 1 0,000480 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3392) = 1
Bei der Abfrage für die Ausgabe auf fd6 tritt keine Blockierung auf, und wenn nur fd10 für die Eingabe abgefragt wird, tritt eine Blockierung von etwa 10 ms auf. Dies spiegelt sich sowohl im Bericht über die Dauer des Systemaufrufs als auch im Intervall zwischen Systemaufrufen wider (sie sind konsistent).
Fehlerfall (extremes Beispiel):
0,000305 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3543) = 1 0.010730 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3533) = 1 0,000475 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL}, {fd = 6, events = POLLOUT | POLLERR | POLLNVAL, revents = POLLOUT}], 2, 3532) = 1 0,000329 poll ([{fd = 10, events = POLLIN | POLLERR | POLLNVAL, revents = POLLIN}], 1, 3532) = 1 0,953349 Umfrage ([{fd = 10, Ereignisse = POLLIN | POLLERR | POLLNVAL}, {fd = 6, Ereignisse = POLLOUT | POLLERR | POLLNVAL, Revents = POLLOUT | POLLERR}], 2, 2578) = 1
Beachten Sie in diesem Fall, dass der vorletzte Anruf zwar 10 ms (normal) dauert, jedoch 953 ms vor dem letzten Anruf liegt.
Mit welchen Tools kann ich den Täter ausfindig machen?
Antworten:
perf
kann für Sie hilfreich sein. Es ist Teil der Linux-Kernel-Dienstprogramme.Zum Beispiel:
Es werden alle Syscall-Eingangs- / Ausgangszeiten und -Parameter (wie strace) angezeigt, der Name der Binärdatei angegeben, die den Syscall aufruft, und der Callstack jeder CPU mit einer bestimmten Frequenz (einschließlich Kernelsymbolen) abgetastet. So können Sie tatsächlich sehen, welcher Code während des Systemaufrufs ausgeführt wurde. In einem Multiprozessorsystem müssen Sie auf die CPU-ID achten (z. B. [001]).
quelle
Vielleicht
atop
können Sie etwas Licht in Ihr Problem bringen.Es kann Prozesse anzeigen, die bereits beendet wurden, und es kann CPU , Speicher anzeigen , Festplatte und Netzwerk anzeigen anzeigen.
Sie können es interaktiv ausführen, in eine Textdatei schreiben lassen oder wie folgt ausführen
sar
in einem vordefinierten Intervall und eine binäre Verlaufsdatei erstellen, die Sie anschließend durchlaufen können.Ich benutze es, um Schweine aller Art zu finden, die schwer zu finden sind :-)
quelle