Proceso con un uso de CPU del 1 % que genera una carga promedio de 1,5

Proceso con un uso de CPU del 1 % que genera una carga promedio de 1,5

Recientemente observamos un promedio de carga alto de aproximadamente 1,5 en nuestro sistema integrado, a pesar de que supuestamente todos los procesos están inactivos (según htop).

El sistema en cuestión es un Cortex-A9 de doble núcleo que ejecuta un kernel de Linux en tiempo real (4.14.126) creado con buildroot. Estamos usando initramfs para nuestro sistema de archivos raíz y no hay intercambio, por lo que definitivamente haysin E/S de discodurante el funcionamiento normal.

Después de investigar un poco, descubrimos que la carga es causada por un programa llamadoactualizar, que nos proporciona una cómoda interfaz web para actualizaciones de software (y nos gustaría mucho seguir usándola).

Cuando suelo timeestimar el uso promedio de CPU de esa aplicación (calculando(usuario+sistema)/real), obtengo un valor de sólo alrededor del 1%, lo que no tiene mucho sentido considerando la carga promedio de 1,5.

Sé que el promedio de carga también incluye procesos en el TASK_UNINTERRUPTIBLEestado que no contribuyen al uso de la CPU. Lo que no entiendo es por qué alguno de los subprocesos/procesos de esa aplicación estaría alguna vez en ese estado.

Para analizar más a fondo la situación, he capturado un seguimiento del kernel usandoltng, lo que muestra que lo único que hace swupdate es esto (cada 50 ms): ingrese la descripción de la imagen aquí

y esto (cada 100 ms): ingrese la descripción de la imagen aquí

Como puede ver, hay un poco de lo que parece ser IPC basado en sockets y una selección en espera dealgo. En el caso de IPC, un hilo parece estar bloqueando principalmente nanosleep(), mientras que el otro está bloqueando accept(), ninguno de los cuales debería consumir recursos del sistema, hasta donde yo sé.

Para su información: la base de tiempo para ambas capturas de pantalla es la misma y el IPC tarda aprox. 500-600 µs en total (lo que, considerando el intervalo de 50 ms, encaja bastante bien con el 1 % de uso de CPU observado)

Entonces, ¿qué está causando la carga aquí?

Respuesta1

Dado que las tareas tanto en el estado R como en D contribuyen a la carga de Linux, puede probar todos los subprocesos de su sistema en cualquiera de estos estados. Por ejemplo:

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

Como resultado del ejemplo a continuación, deberá ignorar la línea superior que muestra su propio psproceso siempre activo, ya que es el que realiza todo el muestreo:

# 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

A menos que esté ejecutando un kernel antiguo, debe ejecutarlo como root ya que los kernels más nuevos enmascaran los valores WCHAN de los procesos de otros usuarios.

Puede ir más allá de eso (pero no con ps), puede probar /proc/PID/syscally /proc/PID/stackobtener información de seguimiento de la pila del kernel y de llamadas al sistema también. He escrito una herramienta llamada Linux Process Snapper ( psn) para esto, de modo que pueda realizar un análisis bastante avanzado de dichos problemas de rendimiento sin tener que recurrir al seguimiento del kernel:

[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       

Puedes ir mucho más allá, una entrada de blog relevante está aquí:

Respuesta2

El uso y la carga de la CPU son métricas diferentes. De hecho, la carga podría estar por encima de 1. La CPU es el tiempo real utilizado por la CPU, por lo que siempre debe ser inferior al 100% (pero en múltiples núcleos/CPU, pero se entiende la idea). Carga indica la carga: cuántos procesos se están ejecutando y esperando ser ejecutados.

Como probablemente sepa (por la discusión en su pregunta), la E/S generalmente es una de esas esperas, por lo que aumenta las cargas. Pero también puede tener señales/semáforos/bloqueos que podrían causar espera, y estos pueden ser causados ​​simplemente por un proceso que no está realizando E/S). Por ejemplo, si un proceso se activa cada segundo y hay muchos procesos que están esperando datos de dicho proceso, obtendrá una carga mayor (igual a la cantidad de procesos en espera).

Es posible que vea las tuberías como E/S, pero mmap y locks... ¿se clasifican como IO? No aparecerán en la biografía (bloqueo de E/S), por lo que es posible que no los veas en muchas estadísticas de carga.

A menudo, la forma más sencilla de averiguarlo es bloquear un proceso y comprobar dónde se encuentra. Hágalo muchas veces y, con suerte, debería ver que una función se está bloqueando (y es posible que la encuentre con mucha más frecuencia que otras funciones).

Respuesta3

Estaba teniendo el mismo problema en un sistema integrado que se ejecuta en un i.mx28 a aproximadamente 450 MHz.

htopconstantemente mostraba un 50% de uso de CPU, causado únicamente por una de las swupdatetareas.

Al navegar a través de mongoose_interface.csu observación de 100 ms activada al leer esto al final de start_mongoose():

                mg_mgr_poll(&mgr, 100);

Experimentalmente cambié 100 a 1000 y después de volver a compilar y reiniciar, el uso de la CPU se redujo a aproximadamente el 2 % de los swupdatesubprocesos, como se observa en htop.

Como dije, esto ha sido experimental ya que los números me parecieron una gran coincidencia. No he investigado si se produce algún efecto secundario.

información relacionada