Un asesino que me desconcierta

No puedo entender por qué el kernel emitiría este asesino cuando veo que hay suficiente memory disponible:

Además, ¿por qué hay tantas páginas de caching del kernel asignadas? Digo que hay suficiente memory disponible después de mirar

Normal

DMA

Líneas libres normales

Este es un dispositivo basado en nand flash con 256 MB de RAM

Kernel: 2.6.31

myshellscript invoked oom-killer: gfp_mask=0xd0, order=2, oomkilladj=0 Backtrace: [<c0106494>] (dump_backtrace+0x0/0x110) from [<c03641a0>] (dump_stack+0x18/0x1c) r6:000000d0 r5:c9040c60 r4:00000002 r3:c0448690 [<c0364188>] (dump_stack+0x0/0x1c) from [<c015a314>] (oom_kill_process.clone.11+0x60/0x1b4) [<c015a2b4>] (oom_kill_process.clone.11+0x0/0x1b4) from [<c015a738>] (__out_of_memory+0x154/0x178) r8:c21e86e0 r7:001fb000 r6:00000002 r5:000000d0 r4:c9b6e000 [<c015a5e4>] (__out_of_memory+0x0/0x178) from [<c015a980>] (out_of_memory+0x68/0xa0) [<c015a918>] (out_of_memory+0x0/0xa0) from [<c015d230>] (__alloc_pages_nodemask+0x42c/0x520) r5:00000002 r4:000000d0 [<c015ce04>] (__alloc_pages_nodemask+0x0/0x520) from [<c015d388>] (__get_free_pages+0x18/0x44) [<c015d370>] (__get_free_pages+0x0/0x44) from [<c0109418>] (get_pgd_slow+0x1c/0xe0) [<c01093fc>] (get_pgd_slow+0x0/0xe0) from [<c0129ab0>] (mm_init.clone.43+0xb0/0xf0) r7:c90858c0 r6:00000000 r5:c90858c0 r4:ce1a6680 [<c0129a00>] (mm_init.clone.43+0x0/0xf0) from [<c0129c40>] (mm_alloc+0x34/0x44) r6:0009230c r5:c90858c0 r4:ce1a6680 r3:00000000 [<c0129c0c>] (mm_alloc+0x0/0x44) from [<c0180f70>] (bprm_mm_init+0x14/0x148) r4:c5154000 r3:cd472564 [<c0180f5c>] (bprm_mm_init+0x0/0x148) from [<c01812d0>] (do_execve+0xa8/0x254) [<c0181228>] (do_execve+0x0/0x254) from [<c0106000>] (sys_execve+0x3c/0x5c) [<c0105fc4>] (sys_execve+0x0/0x5c) from [<c0102e80>] (ret_fast_syscall+0x0/0x2c) r7:0000000b r6:0009230c r5:0009237c r4:000922fc Mem-info: DMA per-cpu: CPU 0: hi: 18, btch: 3 usd: 0 Normal per-cpu: CPU 0: hi: 42, btch: 7 usd: 0 Active_anon:28162 active_file:16 inactive_anon:18037 inactive_file:13 unevictable:0 dirty:0 writeback:0 unstable:0 free:9998 slab:2447 mapped:164 pagetables:701 bounce:0 DMA free:17128kB min:1560kB low:1948kB high:2340kB active_anon:51068kB inactive_anon:10320kB active_file:24kB inactive_file:0kB unevictable:0kB present:97536kB pages_scanned:0 all_unreclaimable? no lowmem_reserve[]: 0 158 158 Normal free:22864kB min:2600kB low:3248kB high:3900kB active_anon:61580kB inactive_anon:61828kB active_file:40kB inactive_file:52kB unevictable:0kB present:162560kB pages_scanned:0 all_unreclaimable? no lowmem_reserve[]: 0 0 0 DMA: 2358*4kB 912*8kB 25*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 17128kB Normal: 4266*4kB 657*8kB 32*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 22864kB 26591 total pagecache pages 0 pages in swap cache Swap cache stats: add 0, delete 0, find 0/0 Free swap = 0kB Total swap = 0kB 65536 pages of RAM 10471 free pages 3967 reserved pages 2447 slab pages 892 shanetworking page count 389 shanetworking pages 620 mapped shanetworking page count 177 mapped shanetworking pages 0 pages swap cached 2481 dma reserved pages 19892 total user pages 20512 RSS sum by tasks 20512 RSS sum by page stats 164 user cache pages 26427 kernel cache pages 

Editar: esta respuesta es incorrecta. Aunque todavía es una posible causa para invocar al asesino mortal, no es la causa en este caso específico.


Parece que esto se debe a la fragmentación de la memory.

A partir de la salida que proporcionó, el bloque de memory contigua de mayor order que tiene es un bloque de 32 kb en la zona normal . Esto significa que si algo trata de asignar un trozo de memory de más de 32kb, fallará.
Normalmente, esto no significa necesariamente que se invocará el asesino mortal (de lo contrario, una aplicación podría solicitar una gran cantidad de memory y, por lo tanto, desencadenar OOM), sin embargo, este es el kernel que está tratando de asignar memory, por lo que es un poco más grave. En este caso exacto, parece que la asignación se desencadenó al iniciar un nuevo process, y el kernel estaba tratando de asignar memory para ese process.

El kernel intenta automáticamente compactar (desfragmentar) la memory y get fragments más grandes de memory contigua disponible, pero algunas páginas no se pueden mover. Y cuanto más time se está ejecutando el sistema, más dispersas se vuelven estas páginas "inamovibles".

Entonces, básicamente, no hay mucho que puedas hacer. Realmente, la única opción es eliminar los processs para que esas páginas inamovibles puedan liberarse.


En cuanto a lo que en ese resultado anterior indica la fragmentación de la memory, son las siguientes líneas

  DMA: 2358*4kB 912*8kB 25*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 17128kB Normal: 4266*4kB 657*8kB 32*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 22864kB 

Una input como 32*16kb significa que hay 32 segmentos contiguos de 16kb libres de memory.

Estamos tratando con una aplicación desconocida en una plataforma incrustada desconocida. Obviamente, si tuviéramos más información sobre esos dos puntos, podríamos tener una mejor oportunidad de responder la pregunta de abc. También sería útil saber exactamente cuánta memory está intentando adquirir el script.


Creo que Patrick está en lo cierto: no hay suficiente DMA contigua para poder permitir que el process se ejecute. Esto podría ser por las siguientes razones posibles:

  1. El sistema integrado puede tener una implementación personalizada de pagination
  2. El sistema integrado podría no tener una MMU
  3. La secuencia de commands podría estar invocando un controller IO que accede al DMA exactamente
  4. La secuencia de commands podría contener progtwigs de terceros que requieren memory contigua

etc …

Creo que si networkinguce la fragmentación de la memory DMA, el asesino OOM no saltará. La forma más fácil de probarlo rápidamente es reiniciar el dispositivo integrado y ver si todavía se está llamando al asesino OOM.

Continuaré yendo y viniendo por internet buscando una forma amigable integrada y liviana de des-fragmentar mi memory sin reiniciar su dispositivo.

Este enlace puede ser de interés: http://bl0rg.krunch.be/oom-frag.html