Prozess mit 1 % CPU-Auslastung verursacht durchschnittliche Auslastung von 1,5

Prozess mit 1 % CPU-Auslastung verursacht durchschnittliche Auslastung von 1,5

Wir haben kürzlich eine hohe durchschnittliche Auslastung von etwa 1,5 auf unserem eingebetteten System festgestellt, obwohl (laut htop) praktisch alle Prozesse schlafen sollten.

Das fragliche System ist ein Dual-Core Cortex-A9 mit einem Echtzeit-Linux-Kernel (4.14.126), der mit Buildroot erstellt wurde. Wir verwenden initramfs für unser Root-Dateisystem und es gibt keinen Swap, also gibt es definitivkein Festplatten-E/Awährend des Normalbetriebs.

Nach einigem Suchen fanden wir heraus, dass die Belastung durch ein Programm namensswupdate, das uns eine praktische Weboberfläche für Software-Updates bietet (und das wir sehr gerne auch weiterhin nutzen möchten).

Wenn ich timedie durchschnittliche CPU-Auslastung dieser Anwendung schätze (durch Berechnung(Benutzer+Sys)/Real), erhalte ich einen Wert von nur etwa 1 %, was angesichts der durchschnittlichen Auslastung von 1,5 nicht viel Sinn macht.

Ich weiß, dass die durchschnittliche Auslastung auch Prozesse in diesem TASK_UNINTERRUPTIBLEZustand umfasst, die nicht zur CPU-Auslastung beitragen. Was ich nicht verstehe, ist, warum sich einer der Threads/Prozesse dieser Anwendung jemals in diesem Zustand befinden sollte.

Um die Situation weiter zu analysieren, habe ich einen Kernel-Trace aufgezeichnet mitltng, was zeigt, dass swupdate nur Folgendes macht (alle 50 ms): Bildbeschreibung hier eingeben

und dies (alle 100 ms): Bildbeschreibung hier eingeben

Wie Sie sehen können, gibt es ein wenig von dem, was wie Socket-basiertes IPC aussieht, und eine Auswahl wartet aufetwas. Im IPC-Fall scheint ein Thread größtenteils in zu blockieren nanosleep(), während der andere in blockiert accept(). Soweit ich weiß, sollte keiner von beiden Systemressourcen verbrauchen.

Zu Ihrer Information: Die Zeitbasis für beide Screenshots ist dieselbe, und der IPC dauert insgesamt ca. 500-600µs (was angesichts des Intervalls von 50ms ganz gut zur beobachteten CPU-Auslastung von 1% passt)

Was also verursacht hier die Belastung?

Antwort1

Da Tasks sowohl im Status R als auch im Status D zur Linux-Last beitragen, können Sie alle Threads in Ihrem System in einem dieser beiden Zustände abfragen. Beispiel:

for x in {1..100} ; do ps -aeos,user,comm,wchan | grep "^[RD]" ; sleep 0.1 ; done | sort | uniq -c | sort -nbr | head -20

Unten sehen Sie ein Beispiel für die Ausgabe. Sie müssen die oberste Zeile ignorieren, die Ihren eigenen psProzess anzeigt, der immer aktiv ist, da dieser die gesamte Abtastung durchführt:

# for x in {1..100} ; do
>   ps -aeos,user,comm,wchan | grep "^[RD]"
>   sleep 0.1
> done | sort | uniq -c | sort -nbr | head -20

    100 R root     ps              -
      3 R oracle   oracle_14047_li -
      2 R root     rcu_sched       rcu_gp_kthread
      2 R root     rcu_sched       -
      2 R root     kworker/1:2-eve -
      2 R oracle   perl            -
      2 R oracle   ora_vktm_lin19c hrtimer_nanosleep
      2 D root     md10_raid10     md_super_wait
      2 D oracle   ora_ckpt_linprd md_write_start
      1 R redis    redis-server    -
      1 R oracle   ora_vktm_linprd hrtimer_nanosleep
      1 R oracle   ora_m001_linprd -
      1 D root     xfsaild/dm-18   rq_qos_wait
      1 D oracle   ora_mz00_lin19c x64_sys_io_destroy
      1 D oracle   ora_lg00_lin19c inode_dio_wait
      1 D oracle   ora_dbrm_lin19c msleep

Sofern Sie keinen alten Kernel verwenden, sollten Sie dies als Root ausführen, da neuere Kernel die WCHAN-Werte der Prozesse anderer Benutzer maskieren.

Sie können noch tiefer gehen (aber nicht mit ps), Sie können Stichproben nehmen /proc/PID/syscallund /proc/PID/stackauch Systemaufruf- und Kernel-Stacktrace-Informationen abrufen. Ich habe psnhierfür ein Tool namens Linux Process Snapper ( ) geschrieben, mit dem Sie ziemlich detaillierte Informationen zu solchen Leistungsproblemen erhalten können, ohne auf Kernel-Tracing zurückgreifen zu müssen:

[tanel@linux01 ~]$ sudo psn -G syscall,wchan

Linux Process Snapper v0.18 by Tanel Poder [https://0x.tools]
Sampling /proc/syscall, stat, wchan for 5 seconds... finished.


=== Active Threads ==========================================================================================

 samples | avg_threads | comm             | state                  | syscall         | wchan                 
-------------------------------------------------------------------------------------------------------------
     511 |      255.50 | (kworker/*:*)    | Disk (Uninterruptible) | [kernel_thread] | blkdev_issue_flush 
     506 |      253.00 | (oracle_*_l)     | Disk (Uninterruptible) | pread64         | do_blockdev_direct_IO 
      28 |       14.00 | (oracle_*_l)     | Running (ON CPU)       | [running]       | 0                     
       1 |        0.50 | (collectl)       | Running (ON CPU)       | [running]       | 0                     
       1 |        0.50 | (mysqld)         | Running (ON CPU)       | [running]       | 0                     
       1 |        0.50 | (ora_lgwr_lin*c) | Disk (Uninterruptible) | io_submit       | inode_dio_wait        
       1 |        0.50 | (oracle_*_l)     | Disk (Uninterruptible) | pread64         | 0                     
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | [running]       | SYSC_semtimedop       
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | [running]       | read_events           
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | read            | 0                     
       1 |        0.50 | (oracle_*_l)     | Running (ON CPU)       | semtimedop      | SYSC_semtimedop       

Sie können noch viel tiefer gehen, einen entsprechenden Blogeintrag finden Sie hier:

Antwort2

CPU-Auslastung und -Last sind unterschiedliche Messwerte. Tatsächlich kann die Auslastung über 1 liegen. CPU ist die tatsächlich von der CPU genutzte Zeit, sie sollte also immer unter 100 % liegen (aber bei mehreren Kernen/CPUs, aber Sie verstehen schon). Die Auslastung gibt die Belastung an: wie viele Prozesse laufen und darauf warten, ausgeführt zu werden.

Wie Sie wahrscheinlich wissen (aus der Diskussion in Ihrer Frage), ist I/O normalerweise eine solche Wartezeit, sodass die Belastung zunimmt. Es kann aber auch Signale/Semaphoren/Sperren geben, die zu Wartezeiten führen können, und diese können nur durch einen Prozess verursacht werden, der keine I/O durchführt). Wenn beispielsweise jede Sekunde ein Prozess aktiviert wird und viele Prozesse auf Daten von diesem Prozess warten, ist die Belastung höher (entspricht der Anzahl der wartenden Prozesse).

Pipes werden Ihnen möglicherweise als E/A angezeigt, aber mmap und Sperren ... klassifizieren Sie sie als IO? Sie werden nicht in Bio (Block-E/A) angezeigt, daher werden sie Ihnen möglicherweise in vielen Ladestatistiken nicht angezeigt.

Dies lässt sich häufig am einfachsten herausfinden, indem man einen Prozess blockiert und prüft, wo er sich befindet. Wenn Sie dies mehrmals tun, werden Sie hoffentlich feststellen, dass eine Funktion blockiert (und Sie werden dies möglicherweise häufiger feststellen als andere Funktionen).

Antwort3

Ich hatte das gleiche Problem auf einem eingebetteten System, das auf einem i.mx28 mit etwa 450 MHz lief.

htopzeigte ständig eine CPU-Auslastung von 50 % an, die ausschließlich durch eine der swupdateAufgaben verursacht wurde.

Beim Durchsuchen mongoose_interface.cIhrer 100-ms-Beobachtung, die beim Lesen am Ende von ausgelöst wurde start_mongoose():

                mg_mgr_poll(&mgr, 100);

Ich habe experimentell 100 auf 1000 geändert und nach einer Neukompilierung und einem Neustart sank die CPU-Auslastung auf etwa 2 % der swupdateThreads, wie in beobachtet htop.

Wie gesagt, das war experimentell, da mir die Zahlen zu sehr nach Zufallszahlen vorkamen. Ob irgendwelche Nebenwirkungen auftreten, habe ich nicht untersucht.

verwandte Informationen