Análisis de un bucle sin fin de procesos en modo usuario

1. Fenómeno problemático

El proceso de negocio (programa de subprocesos múltiples en modo de usuario) se bloquea, el sistema operativo no responde y el registro del sistema no presenta anomalías. Desde la pila de modo de kernel del proceso, parece que todos los subprocesos están atascados en el siguiente flujo de pila de modo de kernel:
[root @ vmc116 ~] # cat / proc / 27007 / task / 11825 / stack
[] retint_careful + 0x14 / 0x32
[ ] 0xffffffffffffffff

2, el análisis de puntos problemáticos

2.1, análisis de la pila del kernel

Desde la pila del kernel, todos los procesos están bloqueados en retint_careful. Este es el proceso del proceso de retorno de interrupciones. El código (ensamblado) es el siguiente:
entry_64.S:

ret_from_intr:
    DISABLE_INTERRUPTS(CLBR_NONE)
    TRACE_IRQS_OFF
    decl PER_CPU_VAR(irq_count)

    /* Restore saved previous stack */
    popq %rsi
    CFI_DEF_CFA rsi,SS+8-RBP    /* reg/off reset after def_cfa_expr */
    leaq ARGOFFSET-RBP(%rsi), %rsp
    CFI_DEF_CFA_REGISTER    rsp
    CFI_ADJUST_CFA_OFFSET    RBP-ARGOFFSET
...
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

Este es en realidad el proceso de regresar de la interrupción después de que el modo de usuario interrumpe el proceso de modo de usuario, combinado con retint_careful + 0x14 / 0x32, y desarmado, puede confirmar que el punto de bloqueo está realmente en SCHEDULE_USER,
que en realidad está llamando a schedule () para programar , Es decir, cuando el proceso pasa al proceso de retorno de interrupción, se encuentra que necesita ser programado (TIF_NEED_RESCHED está configurado), por lo que la programación ocurre aquí.
Hay una pregunta: ¿Por qué no puedo ver el marco de pila del nivel de schedule () en la pila?
Debido a que esto se llama directamente por ensamblado, no hay operaciones relacionadas de inserción de marco de pila y preservación de contexto.

2.2. Realizar análisis de información de estado

A partir de los resultados del comando superior, los subprocesos relevantes realmente han estado en estado R, la CPU está casi completamente agotada y la mayoría de ellos se consumen en modo de usuario:

[root@vmc116 ~]# top
top - 09:42:23 up 16 days,  2:21, 23 users,  load average: 84.08, 84.30, 83.62
Tasks: 1037 total,  85 running, 952 sleeping,   0 stopped,   0 zombie
Cpu(s): 97.6%us,  2.2%sy,  0.2%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32878852k total, 32315464k used,   563388k free,   374152k buffers
Swap: 35110904k total,    38644k used, 35072260k free, 28852536k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                     
27074 root      20   0 5316m 163m  14m R 10.2  0.5 321:06.17 z_itask_templat                                                                                                                
27084 root      20   0 5316m 163m  14m R 10.2  0.5 296:23.37 z_itask_templat                                                                                                                   
27085 root      20   0 5316m 163m  14m R 10.2  0.5 337:57.26 z_itask_templat                                                                                                                   
27095 root      20   0 5316m 163m  14m R 10.2  0.5 327:31.93 z_itask_templat                                                                                                                   
27102 root      20   0 5316m 163m  14m R 10.2  0.5 306:49.44 z_itask_templat                                                                                                                   
27113 root      20   0 5316m 163m  14m R 10.2  0.5 310:47.41 z_itask_templat                                                                                                                   
25730 root      20   0 5316m 163m  14m R 10.2  0.5 283:03.37 z_itask_templat                                                                                                                   
30069 root      20   0 5316m 163m  14m R 10.2  0.5 283:49.67 z_itask_templat                                                                                                                   
13938 root      20   0 5316m 163m  14m R 10.2  0.5 261:24.46 z_itask_templat                                                                                                                   
16326 root      20   0 5316m 163m  14m R 10.2  0.5 150:24.53 z_itask_templat                                                                                                                   
 6795 root      20   0 5316m 163m  14m R 10.2  0.5 100:26.77 z_itask_templat                                                                                                                   
27063 root      20   0 5316m 163m  14m R  9.9  0.5 337:18.77 z_itask_templat                                                                                                                   
27065 root      20   0 5316m 163m  14m R  9.9  0.5 314:24.17 z_itask_templat                                                                                                                   
27068 root      20   0 5316m 163m  14m R  9.9  0.5 336:32.78 z_itask_templat                                                                                                                   
27069 root      20   0 5316m 163m  14m R  9.9  0.5 338:55.08 z_itask_templat                                                                                                                   
27072 root      20   0 5316m 163m  14m R  9.9  0.5 306:46.08 z_itask_templat                                                                                                                   
27075 root      20   0 5316m 163m  14m R  9.9  0.5 316:49.51 z_itask_templat                                                                                                                   
...

2.3, información de programación de procesos

De la información de programación de los subprocesos relacionados:
[root @ vmc116 ~] # cat / proc / 27007 / task / 11825 / schedstat
15681811525768 129628804592612 3557465
[root @ vmc116 ~] # cat / proc / 27007 / task / 11825 /
schedstat 15683057685046925
[root @ vmc116 ~] # cat / proc / 27007 / tarea / 11825 / schedstat
15682843570331 129638127548315 3557686
[root @ vmc116 ~] # cat / proc / 27007 / tarea / 11825 / schedstat
15683323640217 129642447477861 3557793
[root @ vmc116 ~] # cat / proc / 27007 / task / 11825 / schedstat
15683698477621 129645817640726 3557875
encontró que las estadísticas de programación de subprocesos relacionados han aumentado, lo que indica que los subprocesos relacionados se han programado para ejecutarse, combinado con su estado siempre ha sido R, se especuló que es probable que ocurra en modo de usuario Bucle muerto (o punto muerto sin suspensión).

Aquí hay otra pregunta : ¿Por qué la ocupación de CPU de cada subproceso es solo alrededor del 10% desde la parte superior, en lugar del 100% de ocupación causada por el proceso de bucle infinito que generalmente se ve?
Debido a que hay muchos subprocesos y sus prioridades son todas iguales, de acuerdo con el algoritmo de programación de CFS, los intervalos de tiempo se distribuirán uniformemente y un subproceso no monopolizará la CPU. El resultado es que se programan varios subprocesos a su vez, consumiendo toda la CPU. .
Otra pregunta: ¿Por qué el kernel no detecta softlockup en este caso?
Debido a que la prioridad del proceso empresarial no es alta, no afectará la programación del subproceso del kernel de vigilancia (el subproceso en tiempo real de mayor prioridad), por lo que no habrá bloqueo suave.
Otra pregunta: ¿Por qué siempre se bloquea en retint_careful cada vez que veo la pila de subprocesos y no en otro lugar?
Debido a que este (cuando la interrupción regresa) es el momento de la programación, la programación no puede ocurrir en otros puntos en el tiempo (independientemente de otras circunstancias ~), y verificamos el comportamiento de la pila de subprocesos, que también debe depender de la programación del proceso, por lo que verificamos cada vez Al apilar, es cuando se programa el proceso que mira la pila (comando cat), y es cuando regresa la interrupción, por lo que el punto de bloqueo que se acaba de ver es retint_careful.

2.4, análisis de la actitud del usuario

A partir del análisis anterior, se especula que se produjo un interbloqueo en el modo de usuario (un interbloqueo no puede ocurrir aquí, si ocurre un interbloqueo, debe haber un proceso que esté bloqueado en el modo de kernel ). La pila del kernel mutex es la siguiente:

Detaching from program: /sbc/wq/some_func/share_mem_mutex, process 29758
[root@localhost ~]# cat /proc/29758/stack
[<ffffffff810a4179>] futex_wait_queue_me+0xb9/0xf0
[<ffffffff810a53a8>] futex_wait+0x1f8/0x390
[<ffffffff810a6c11>] do_futex+0x121/0xb10
[<ffffffff810a767b>] sys_futex+0x7b/0x170
[<ffffffff8100b0d2>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

En este punto, el modo de usuario se puede usar para confirmar el método:
implementar la información de depuración, luego gdb adjuntar el proceso relevante, confirmar la pila y combinar el análisis lógico del código.
Finalmente se confirma que el problema es de hecho un bucle sin fin en el proceso del modo de usuario.

Supongo que te gusta

Origin blog.csdn.net/wangquan1992/article/details/108508701
Recomendado
Clasificación