使用するメモリ(「58 * 4096kB(C)」など)がまだ十分ですが、「ページ割り当て失敗」が表示されるのはなぜですか?

使用するメモリ(「58 * 4096kB(C)」など)がまだ十分ですが、「ページ割り当て失敗」が表示されるのはなぜですか?

「58*4096kB(C)」を使用できますが、「ページ割り当て失敗」が表示されるのはなぜですか。

ご存知のように、カーネルは、order:10サイズのメモリを割り当てると文句を言います(つまり、ページ割り当てに失敗しました:order:10)。ただし、実際には利用可能なブロック(「58 * 4096kB(C)」など)があります。だから実際に利用可能なメモリが十分なので文句を言ってはいけないと思います。

関連ログは次のとおりです。

[ 2161.623563] xxxx: page allocation failure: order:10, mode:0x2084020(GFP_ATOMIC|__GFP_COMP)
[ 2161.632085] CPU: 0 PID: 179 Comm: AiApp Not tainted 4.9.56 #53
[ 2161.637947] 
Call Trace:
[<802f63f2>] dump_stack+0x1e/0x3c
[<800f6cf4>] warn_alloc+0x100/0x148
[<800f709c>] __alloc_pages_nodemask+0x2bc/0xb5c
[<801120fe>] kmalloc_order+0x26/0x48
[<80112158>] kmalloc_order_trace+0x38/0x98
[<8012c5d8>] __kmalloc+0xf4/0x12c
[<8048ac78>] alloc_ep_req+0x5c/0x98
[<8048f232>] source_sink_recv+0x2a/0xe0
[<8048f35e>] usb_sourcesink_bulk_read+0x76/0x1c8
[<8048f770>] usb_sourcesink_read+0xfc/0x2c8
[<80134d58>] __vfs_read+0x30/0x108
[<80135c14>] vfs_read+0x94/0x128
[<80136d12>] SyS_read+0x52/0xd4
[<8004a246>] csky_systemcall+0x96/0xe0
[ 2161.689204] Mem-Info:
[ 2161.691518] active_anon:3268 inactive_anon:2 isolated_anon:0
[ 2161.691518]  active_file:1271 inactive_file:89286 isolated_file:0
[ 2161.691518]  unevictable:0 dirty:343 writeback:0 unstable:0
[ 2161.691518]  slab_reclaimable:2019 slab_unreclaimable:644
[ 2161.691518]  mapped:4282 shmem:4 pagetables:59 bounce:0
[ 2161.691518]  free:62086 free_pcp:199 free_cma:60234

[ 2161.724334] Node 0 active_anon:13072kB inactive_anon:8kB active_file:5084kB inactive_file:357144kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:17128kB dirty:1372kB writeback:0kB shmem:16kB writeback_tmp:0kB unstable:0kB pages_scanned:0 all_unreclaimable? no

[ 2161.748626] Normal free:248344kB min:2444kB low:3052kB high:3660kB active_anon:13072kB inactive_anon:8kB active_file:5084kB inactive_file:357144kB unevictable:0kB writepending:1372kB present:1048572kB managed:734568kB mlocked:0kB slab_reclaimable:8076kB slab_unreclaimable:2576kB kernel_stack:608kB pagetables:236kB bounce:0kB free_pcp:796kB local_pcp:796kB free_cma:240936kB
[ 2161.781670] lowmem_reserve[]: 0 0 0

[ 2161.785225] Normal: 4*4kB (UEC) 3*8kB (EC) 3*16kB (UEC) 2*32kB (UE) 2*64kB (UE) 2*128kB (UE) 2*256kB (EC) 1*512kB (E) 3*1024kB (UEC) 3*2048kB (UEC) 58*4096kB (C) = 248344kB
90573 total pagecache pages

[ 2161.803526] 262143 pages RAM
[ 2161.806410] 0 pages HighMem/MovableOnly
[ 2161.810264] 78501 pages reserved
[ 2161.813509] 90112 pages cma reserved

ベストアンサー1

これが起こる条件、実行中のシステム(Linux、Androidなど)など、多くの情報を提供していません。

とにかくカーネルの微調整を始めることができます。を使用すると、vm.min_free_kbytesカーネルがすべての状況でそのメモリをKiB単位で自由に保つように指示できます。

~からkernel.org ドキュメント ("/proc/sys/vm/* のドキュメント"):

利用可能な最小キロバイト:

これは、Linux VMが利用可能な最小キロバイト数を維持するために使用されます。 VMはこの数値を使用して、WMARK_MINシステムの各lowmem領域のwatermark []値を計算します。各lowmem領域は、サイズに比例して予約された無料ページ数を取得します。

割り当てを満たすには最小メモリ量が必要です。 1024KB **PF_MEMALLOC 未満に設定すると、システムが微妙に損傷し、高負荷でデッドロックが発生しやすくなります。

高すぎると、デバイスはすぐにOOM状態になります。

これを永久に変更するには、次の操作を実行できます(最大16MiB)。

echo "vm.min_free_kbytes=16384" >> /etc/sysctl.conf

すべてが正しく機能しているかどうかをテストするには、現在のセッションに対してのみ変更できます。

sysctl -w vm.min_free_kbytes=16384

この情報のソースはkernel.org ドキュメント


あなたの質問は、上記のものよりも多くの空きメモリがあるにもかかわらず、空きメモリがあるとページエラーが発生するのはなぜですか?

使用可能なメモリが指定された制限を超えると、vm.min_free_kbytes答えが出る可能性が高くなります。メモリの断片化 (メモリモジュールの故障などの他の問題がある可能性があります。)

詳細は次のとおりです。

order:10ビットは、要求されたページ数を間接的に通知します。これらの順序は、実際には1024ページまたは4096KiBの連続メモリに対応する2 10(2 ^ 10)を要求するため、親順序と見なされます。

これはmodeカーネルメモリアロケータに渡されるフラグです。mode:0x2084020 (GFP_ATOMIC|__GFP_COMP) - カーネルモードアロケータ(フラグ)があります。これにはカーネルソースコードの知識が必要です。ロゴを詳しく説明してください。

バナーGFP_ATOMIC:

このGFP_ATOMICフラグは、メモリアロケータがブロックされないことを示します。割り込みハンドラ、サブハーフ、ロックを保持するプロセスコンテキストコードなど、スリープモードが不可能な(原子的に維持する必要がある)状況でこのフラグを使用します。カーネルは割り当てをブロックできず、要求を満たすのに十分なメモリを解放しようとするため、指定された割り当ては、指定されていない割り当てGFP_ATOMICよりも成功の​​可能性が低くなります。しかし、現在の環境で睡眠が不可能な場合は、これが唯一の選択です。 …

バナー__GFP_COMP:

複合ページメタデータ

include/linux/gfp.hで(参照:ソース1ソース2)。

このページフレームは拡張ページに属します。

これは必要なメモリ量に戻ります。拡張ページを使用すると、4KiBではなく4MiBページフレームを持つことができます。おすすめの本: Linuxカーネル本と素晴らしい記事: Kernel Korner - カーネルにメモリを割り当てます。より多くの情報を知りたいです。

ご覧のとおり、4096 KiBの非ブロック割り当てを要求しており、割り当てはアトミックに維持する必要があります。割り当てをブロックしてメモリを(連続的に)解放しようとすることはできません。したがって、割り当てが失敗しました。

フラグは以下にありますinclude/linux/gfp.h (参照ソース1ソース2)。

編集 – カーネルバージョン4.9

これはカーネルバージョン4.9に関する重要な情報です。この正確なカーネルバージョン(4.9)には、SWAPがまったく機能しないようにする回帰がありました。OOMですが、スワップ領域は使用されません(kernel.org)

この問題を解決するための推奨される方法は、カーネルを4.10.8以降にアップグレードすることです。このバグはこのバージョン以降で修正する必要があります。詳細についてはをご覧ください。OOMですが、スワップ領域は使用されません(Red Hat)

__________________
*    おそらくキロバイトを意味するようです。
**おそらくKiBを意味します。

おすすめ記事