Ein Oom-Killer, der mich verblüfft

7

Ich kann nicht verstehen, warum der Kernel diesen OOM-Killer ausgeben sollte, wenn ich sehe, dass genügend Speicher verfügbar ist:

Warum werden so viele Kernel-Cache-Seiten zugewiesen? Ich sage, nach dem Betrachten ist genügend Speicher verfügbar

Normal

DMA

Normale freie Leitungen

Dies ist ein eingebettetes nand Flash-basiertes Gerät mit 256 MB 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 shared page count 
 389 shared pages
 620 mapped shared page count
 177 mapped shared 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
Ankur Agarwal
quelle
1
Ist das 32bit? Wie oft passiert es? Ist es leicht reproduzierbar? Ich würde mit Bedacht prüfen, wie viel der Prozess tatsächlich zuweist.
Klapaucius

Antworten:

6

Bearbeiten: Diese Antwort ist falsch. Obwohl immer noch eine mögliche Ursache für das Aufrufen von Oom-Killer ist, ist dies in diesem speziellen Fall nicht die Ursache.


Es sieht so aus, als ob dies auf eine Speicherfragmentierung zurückzuführen ist.

Von der von Ihnen bereitgestellten Ausgabe ist der zusammenhängende Speicherblock höchster Ordnung, den Sie haben, ein 32-KB-Block in der normalZone. Dies bedeutet, dass ein Fehler auftritt, wenn versucht wird, einen Speicherblock mit mehr als 32 KB zuzuweisen.
Normalerweise bedeutet dies nicht unbedingt, dass der OOM-Killer aufgerufen wird (andernfalls könnte eine Anwendung einen großen Speicherblock anfordern und somit OOM auslösen). Dies ist jedoch der Kernel, der versucht, Speicher zuzuweisen, und daher ist es ein bisschen mehr ernst. In genau diesem Fall scheint die Zuweisung durch Starten eines neuen Prozesses ausgelöst worden zu sein, und der Kernel hat versucht, Speicher für diesen Prozess zuzuweisen.

Der Kernel versucht automatisch, den Speicher zu komprimieren (zu defragmentieren) und größere Teile des zusammenhängenden Speichers verfügbar zu machen. Einige Seiten können jedoch nicht verschoben werden. Und je länger das System läuft, desto verstreuter werden diese "unbeweglichen" Seiten.

Im Grunde kann man nicht viel tun. Die einzige Möglichkeit besteht darin, Prozesse abzubrechen, damit diese nicht beweglichen Seiten freigegeben werden können.


Was in der obigen Ausgabe die Speicherfragmentierung anzeigt, sind die folgenden Zeilen

 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

Ein Eintrag wie 32*16kbbedeutet, dass 32 zusammenhängende 16-KB-Speicherblöcke frei sind.

Patrick
quelle
Aber aus den Protokollen versuche ich, Reihenfolge 2 Seiten zuzuweisen. Und es sind genügend Bestellseiten 3 verfügbar. Warum wird Oom Killer immer noch angerufen? "gfp_mask = 0xd0, order = 2"
Ankur Agarwal
@abc du hast recht, das habe ich komplett verpasst. Ich habe den Kernel-Code durchgesehen (allerdings nicht 2.6.31, aber eine enge Version), und ich sehe nichts herausspringen :-(
Patrick
1

Wir haben es mit einer unbekannten Anwendung auf einer unbekannten eingebetteten Plattform zu tun. Wenn wir mehr Informationen zu diesen beiden Punkten hätten, hätten wir natürlich eine bessere Chance, die Frage von abc zu beantworten. Es wäre auch nützlich, genau zu wissen, wie viel Speicher das Skript zu erfassen versucht.


Ich denke, Patrick hat Recht - es gibt nicht genügend zusammenhängende DMA, um den Prozess laufen zu lassen. Dies kann folgende Gründe haben:

  1. Das eingebettete System verfügt möglicherweise über eine benutzerdefinierte Implementierung von Paging
  2. Das eingebettete System verfügt möglicherweise nicht über eine MMU
  3. Das Skript ruft möglicherweise einen E / A-Treiber auf, der genau auf den DMA zugreift
  4. Das Skript kann Programme von Drittanbietern enthalten, die zusammenhängenden Speicher benötigen

usw...

Ich glaube, wenn Sie die DMA-Speicherfragmentierung reduzieren würden, würde der OOM-Killer nicht springen. Der einfachste Weg, dies schnell zu testen, besteht darin, das eingebettete Gerät neu zu starten und festzustellen, ob der OOM-Killer noch aufgerufen wird.

Ich werde jetzt weiter im Internet herumtollen und nach einer leichten, eingebetteten, freundlichen Methode suchen, um das eigene Gedächtnis zu entfragmentieren, ohne das Gerät zurückzusetzen.

Dieser Link kann von Interesse sein: http://bl0rg.krunch.be/oom-frag.html

OldTinfoil
quelle