web-dev-qa-db-ja.com

私を困惑させているoomキラー

十分なメモリが利用可能であることがわかったときに、カーネルがこのoomkillerを発行する理由を理解できません。

また、なぜこれほど多くのカーネルキャッシュページが割り当てられているのですか?見てみると十分なメモリがあると思います

正常

DMA

通常のフリーライン

これは、256MBのRAMを搭載した組み込みNANDフラッシュベースのデバイスです。

カーネル: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
7
Ankur Agarwal

編集:この答えは正しくありません。 oom-killerが呼び出される原因はまだ考えられますが、この特定のケースでは原因ではありません。


これはメモリの断片化が原因のようです。

あなたが提供した出力から、あなたが持っている最高位の連続したメモリブロックはnormalゾーンの32kbブロックです。これは、32kbを超えるメモリのチャンクを割り当てようとすると、失敗することを意味します。
通常、これは必ずしもoom-killerが呼び出されることを意味するわけではありません(そうでない場合、アプリケーションが大量のメモリを要求してOOMをトリガーする可能性があります)が、これはメモリを割り当てようとしているカーネルであり、ですから、もう少し深刻です。この正確なケースでは、割り当ては新しいプロセスを開始することによってトリガーされ、カーネルはそのプロセスにメモリを割り当てようとしていたようです。

カーネルは自動的にメモリを圧縮(デフラグ)し、連続したメモリのより大きなチャンクを利用できるようにしますが、一部のページは移動できません。また、システムの実行時間が長くなるほど、これらの「移動できない」ページが分散します。

つまり、基本的に、できることはあまりありません。本当に唯一のオプションは、プロセスを強制終了して、移動できないページを解放できるようにすることです。


 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

32*16kbのようなエントリは、32個の16kbの連続したメモリチャンクが空いていることを意味します。

6
Patrick

未知の組み込みプラットフォームで未知のアプリケーションを扱っています。明らかに、これら2つのポイントについてより多くの情報があれば、abcの質問に答える可能性が高くなる可能性があります。スクリプトが取得しようとしているメモリの量を正確に知ることも役立ちます。


Patrickは正しいと思います-プロセスを実行できるようにするための連続したDMAが不十分です。これには、次の理由が考えられます。

  1. 組み込みシステムには、ページングのカスタム実装がある場合があります
  2. 組み込みシステムにMMUがない可能性があります
  3. スクリプトは、IO正確にアクセスするDMAドライバーを呼び出す可能性があります
  4. スクリプトには、連続したメモリを必要とするサードパーティのプログラムが含まれている可能性があります

等...

DMAメモリの断片化を減らした場合、OOMキラーはジャンプしないと思います。これをすばやくテストする最も簡単な方法は、組み込みデバイスを再起動して、OOMキラーがまだ存在するかどうかを確認することです。と呼ばれる。

私は今、インターネットをぶらぶらして、デバイスをリセットせずにメモリの断片化を解除する、軽量で組み込みに適した方法を探しています。

このリンクは興味深いかもしれません: http://bl0rg.krunch.be/oom-frag.html

1
OldTinfoil