Suchen Sie gelegentlich CPU-Kernel-Hog


11

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?


2
Bonuspunkte für die interessante Frage. Ich bin nicht sicher, wie ich es beantworten soll, aber ich habe eine Frage, wie ich es auf die CPU-Auslastung zurückführen kann (im Gegensatz zu Spitzen in iowait zum Beispiel).
Bratchley

1
Die erste Vermutung ist, ob Sie JFFS2 oder YAFFS auf einem großen NAND-Flash ausführen, insbesondere wenn Sie aufnehmen. Deaktivieren Sie alles, was in Flash geschrieben wird, und prüfen Sie, ob dies hilfreich ist. Wie sieht Ihre Prozesstabelle aus? Sie können ftrace als letzten Ausweg verwenden, wenn Sie über eine Toolchain zum Erstellen des Kernels verfügen.
Jonathan Ben-Avraham

sar-bu könnte es tun .. linux.die.net/man/1/sar
Grizly

Es wird ein Blitz verwendet. eine SD-Karte mit einem gemounteten ext4-Dateisystem. Und das Schreiben ist zwar eine mögliche Ursache für diese Probleme (aber warum genau?), Aber wahrscheinlich nicht die einzige.
Awy

Antworten:


1

perfkann für Sie hilfreich sein. Es ist Teil der Linux-Kernel-Dienstprogramme.

Zum Beispiel:

perf record -R -a -g fp -e cycles -e syscalls:sys_enter_poll -e syscalls:sys_exit_poll
#Just ctrl+c if you are done, and view ith
perf script 

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]).


Ich werde versuchen, Perf für die Plattform zu bauen - danke für den Tipp.
Awy

0

Vielleicht atopkö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 :-)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.