Cómo lidiar con el ciclo muerto del proceso de estado de usuario en Linux

  
                

Al realizar operaciones del sistema Linux, a veces se encontrará con un proceso infinito de proceso de usuario, es decir, el sistema es lento, el proceso se bloquea, etc. ¿Cómo resolver estos problemas? La siguiente pequeña serie le presentará el siguiente proceso de proceso infinito del usuario.

1, el fenómeno problema

de procesos de negocio (modo de usuario programas multihilo) vinculado a la muerte, el sistema operativo de registro no responde, el sistema no es ninguna excepción. Apilar a partir del núcleo procesos de modo ver, parece que todos los temas están atrapados en proceso de pila de modo de núcleo de la siguiente manera:

[root @ vmc116 ~] # cat /proc /27007 /tarea /11825 /pila

[ "ffffffff8100baf6"] retint_careful + 0x14 /0x32

[ "ffffffffffffffff"] 0xffffffffffffffff

2, problema de análisis

1) pila análisis kernel

de la mirada pila del núcleo, todos los procesos están bloqueados en retint_careful, este es el proceso de interrupción del flujo de retorno, el código (compilado) de la siguiente manera:

entry_64.S

código como sigue:

ret_from_intr:

DISABLE_INTERRUPTS (CLBR_NONE)

TRACE_IRQS_OFF

decl PER_CPU_VAR (irq_count)

/* Restaurar pila anterior salvado * /

popq% RSI

CFI_DEF_CFA RSI, SS + 8-RBP /* reg /off de restablecimiento después de def_cfa_expr * /

leaq ARGOFFSET-RBP (% RSI),% RSP < Br>

CFI_DEF_CFA_REGISTER rsp

CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET < Br>

. . .

retint_careful:

CFI_RESTORE_STATE

bt $ TIF_NEED_RESCHED, EDX%

JNC retint_signal

TRACE_IRQS_ON

ENABLE_INTERRUPTS ( CLBR_NONE)

pushq_cfi% RDI

SCHEDULE_USER

popq_cfi% RDI

GET_THREAD_INFO (% rcx)

DISABLE_INTERRUPTS (CLBR_NONE)

TRACE_IRQS_OFF

JMP retint_check

esto es en realidad un proceso de modo de usuario se interrumpe después de que el modo de usuario de interrupción, el flujo de retorno de interrupción desde el combinado retint_careful + 0x14 /0x32, desensamblar puede confirmar el punto de bloqueo, de hecho, en

SCHEDULE_USER

este calendario es en realidad llamando al () para programar, es decir, cuando el proceso de interrumpir el flujo vuelve entrar, se encontró la necesidad de programar ( TIF_NEED_RESCHED está establecido, por lo que la programación se produce aquí.

Hay una pregunta: ¿Por qué no puedo ver el marco de pila de schedule () en la pila?

Debido a que el ensamblado lo llama directamente, no hay una operación relacionada de inserción de marco de pila y de guardado de contexto.

2) el estado de análisis de información

En cuanto a los resultados de la orden superior, el tema en cuestión en realidad ha estado en estado R, CPU casi completamente agotada, y la mayoría de ellos son consumidos en modo de usuario:

[root @ vmc116 ~] # top of

top - 09:42:23 hasta 16 días, 2:21, 23 usuarios, el promedio de carga: 84.08, 84.30, 83.62

Tareas: 1037 en total, 85 de funcionamiento, 952 de dormir, 0 se detuvo, 0 zombi

CPU (s): 97,6% nosotros, 2,2% sy, 0,2% de Ni, 0,0% de DI, 0,0% wa, 0,0% hi , 0,0% de Si, 0,0% st

Mem: 32878852k total 32315464k utilizarse, 563388k libre, tampones 374152k

Intercambio: 35110904k total de, 38644k utilizado, 35072260k libre, 28852536k caché

USUARIO PID PR NI VIRT RES SHR S% CPU% MEM TIEMPO + COMANDO

27074 raíz 20 0 5316M 163m 14m R 10,2 0,5 321: 06,17 z_itask_templat

27084 raíz 20 0 5316M 163m 14m R 10.2 0.5 296: 23.37 z_itask_templat

27085 raíz 20 0 5316m 163m 14m R 10.2 0.5 337: 57.26 z_itask _templat

27095 raíz 20 0 5316M 163m 14m R 10,2 0,5 327: 31,93 z_itask_templat

27102 raíz 20 0 5316M 163m 14m R 10,2 0,5 306: 49,44 z_itask_templat

27113 raíz 20 0 5316M 163m 14m R 10,2 0,5 310: 47,41 z_itask_templat

25730 raíz 20 0 5316M 163m 14m R 10,2 0,5 283: 03,37 z_itask_templat

30069 raíz 20 0 5316M 163m 14m R 10,2 0,5 283: 49.67 z_itask_templat

13938 raíz 20 0 5316M 163m 14m R 10,2 0,5 261: 24,46 z_itask_templat

16326 raíz 20 0 5316M 163m 14m R 10,2 0,5 150: 24,53 z_itask_templat

6.795 raíz 20 0 5316M 163m 14m R 10,2 0,5 100: 26,77 z_itask_templat

27063 raíz 20 0 5316M 163m 14m R 9,9 0,5 337: 18,77 z_itask_templat

27065 raíz 20 0 5316M 163m 14m R 9,9 0,5 314: 24.17 z_itask_templat

27068 raíz 20 0 5316M 163m 14m R 9,9 0,5 336: 32,78 z_itask_templat

27069 raíz 20 0 5316M 163m 14m R 9,9 0,5 338: 55,08 z_itask_templat

27072 raíz 20 0 5316M 163m 14m R 9,9 0,5 306: 46,08 z_itask_templat

27075 raíz 20 0 5316M 163m 14m R 9,9 0,5 316: 49,51 z_itask_templat

. . .

3) la información del proceso de programación

información relacionada con la programación de subprocesos del reloj:

[root @ vmc116 ~] # cat /proc /27007 /tarea /11825 /schedstat

15681811525768 129628804592612 3557465

[root @ vmc116 ~] # cat /proc /27007 /tarea /11825 /schedstat

15682016493013 129630684625241 3.557.509

[root @ vmc116 ~] # cat /proc /27007 /tarea /11825 /schedstat

15682843570331 129638127548315 3.557.686

[root @ vmc116 ~] # cat /proc /27007 /tarea /11825 /schedstat

15683323640217 129642447477861 3557793

[root @ vmc116 ~] # cat /proc /27007 /tarea /11825 /schedstat

15683698477621 129645817640726 3.557.875

encontrado subproceso asociado Las estadísticas de programación han aumentado, lo que indica que el subproceso relevante se ha programado para ejecutarse, y su estado siempre ha sido R, especulación de que es probable que tenga un bucle infinito (o punto muerto sin suspensión) en el estado del usuario.

Hay otro problema aquí: ¿Por qué el uso de la CPU de cada subproceso es superior al 10%, en lugar del 100% de ocupación causado por el proceso de bucle infinito que normalmente se ve?

Debido a que muchos hilos, y la prioridad son los mismos, de acuerdo con algoritmo de programación SFC, la asignación media de segmentos de tiempo no va a dejar que uno de los hilos de la CPU exclusiva. El resultado es una programación de turno rotativo entre varios subprocesos, que consume todas las CPU. .

Otra pregunta: ¿Por qué el kernel no está detectando softlockup en este caso?

Debido a que la prioridad del proceso de negocio no es alta, no afectará la programación del subproceso del kernel de watchdog (el subproceso de mayor prioridad en tiempo real), por lo que no habrá bloqueo de software.

Otra pregunta: ¿Por qué siempre bloqueas retint_careful cada vez que miras la pila de hilos, no en otra parte?

Debido a que (tiempo de retorno de interrupción) aquí está el punto de la hora programada, la programación no puede suceder (sin tener en cuenta otros casos ~) en otros momentos, y vemos el comportamiento de la pila hilo, debe confiar en el proceso de programación tiempo, por lo que cada vez que vemos la pila, es la vista de la (comando cat) pila de proceso para obtener la hora programada, entonces es hora de volver a interrumpir, por lo que acaba de ver la retint_careful punto de bloqueo.

4) Análisis del estado del usuario

Del análisis anterior, se supone que el estado del usuario tiene un punto muerto.

Método de confirmación del modo de usuario:

Implemente información de depuración, luego gdb adjunte procesos relacionados, confirme la pila y combine el análisis de la lógica del código.

Confirmación final de que el problema creó un bucle infinito en el proceso de estado del usuario.

Lo anterior es el método de procesamiento del siguiente proceso de estado de usuario del bucle infinito del sistema Linux. Primero, analice la causa del problema y luego trátelo de acuerdo con la razón. ¿Lo ha aprendido?

Copyright © Conocimiento de Windows All Rights Reserved