8

Why does "page allocation failure" occur whereas there are still "58*4096kB (C)" that could be used?

You see, the kernel complains when allocating memory with the size of order:10(i.e.page allocation failure: order:10). But there are free blocks indeed(i.e. "58*4096kB (C)" ). So I think it should not complain since there are enough free memory indeed.

Here is the related log:

[ 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
12
  • 1
    I hope to know the direct reasons for the question. You see, there is still enough memory(i.e. “58*4096kB (C)”) that could be used. Why does not pick a block from this order?
    – John
    Jun 25, 2020 at 8:38
  • 1
    You are welcome. I remember this issue as I had this issue when I was testing CentOS 7 on my server. I found it fishy that the free memory was exactly the same as the sice of the swap. I started to dig around SWAP/memory faults.
    – tukan
    Jun 25, 2020 at 13:10
  • 1
    Can I draw the conclusion that the system still has 62086KB free memory since there is "Mem-Info: ...free:62086"?
    – John
    Jun 25, 2020 at 14:05
  • 1
    free:62086 tells you you have 62086 free pages. It is not kB. That is the 248344kB of free memory which you get some lines below (I have written the count in my answer).
    – tukan
    Jun 25, 2020 at 16:05
  • 1
    I see. Thank you for your generous help.
    – John
    Jun 26, 2020 at 7:40

1 Answer 1

7
+50

You did not provide much information, like what are the condition(s) under which this occurs, which system (Linux, Android,...) are you running, etc.

Anyways you can start fine-tuning your kernel.  You could play around with vm.min_free_kbytes, which tells the kernel to keep such memory free (the unit is KiB) under all circumstances.

From kernel.org documentation ("Documentation for /proc/sys/vm/*"):

min_free_kbytes:

This is used to force the Linux VM to keep a minimum number of kilobytes* free.  The VM uses this number to compute a watermark [WMARK_MIN] value for each lowmem zone in the system.  Each lowmem zone gets a number of reserved free pages based proportionally on its size.

Some minimal amount of memory is needed to satisfy PF_MEMALLOC allocations; if you set this to lower than 1024 KB**, your system will become subtly broken, and prone to deadlock under high loads.

Setting this too high will OOM your machine instantly.

To change this setting permanently you can do (lowering to 16 MiB):

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

To play around and test that everything works, you can change it just for the current session:

sysctl -w vm.min_free_kbytes=16384

The source of the information was kernel.org documentation.


Your question is why you have page fault when you have free memory – even when you have more free memory than specified above?

If you have free memory above the limit specified by vm.min_free_kbytes, then the answer is most likely memory fragmentation (you could have others, like faulty memory modules).

Here are the details:

The order:10 bit tells you indirectly how many pages were requested.  Such order is considered high-order as it actually requests 210 (2^10), which is 1024 pages or 4096 KiB of continuous memory!

The mode are the flags passed to the kernel memory allocator.  You have a mode:0x2084020 (GFP_ATOMIC|__GFP_COMP) – kernel mode allocator (flags).  For this one you need to have some kernel source knowledge.  To explain your flags in detail.

The GFP_ATOMIC flag:

The GFP_ATOMIC flag instructs the memory allocator never to block.  Use this flag in situations where it cannot sleep — where it must remain atomic — such as interrupt handlers, bottom halves and process context code that is holding a lock.  Because the kernel cannot block the allocation and try to free up sufficient memory to satisfy the request, an allocation specifying GFP_ATOMIC has a lesser chance of succeeding than one that does not.  Nonetheless, if your current context is incapable of sleeping, it is your only choice. …

The __GFP_COMP flag:

compound page metadata

From include/linux/gfp.h (see source 1, source 2).

The page frame belongs to extended page

Which comes to the back to the size of memory required.  Extended page allows you to have 4 MiB page frames instead of just 4 KiB.  Recommended reading: the Linux Kernel book and the excellent article: Kernel Korner - Allocating Memory in the Kernel for more information.

As you can see, you are requesting 4096 KiB of non-blocking allocation, allocation must remain atomic; you can't block the allocation and try to free the memory (continuous).  The allocation thus fails.

Flags can be found at include/linux/gfp.h (see source 1, source 2).

Edit – Kernel version 4.9

That is important information the kernel version 4.9.  There has been a regression at this exact kernel version (4.9) which caused SWAP not to be used at all – OOM but no swap used (kernel.org).

Recommended way to fix it is to upgrade kernel to at least 4.10.8.  This version and above should have this bug fixed – more at OOM but no swap used (Red Hat)

__________________
*   Presumably they mean kibibytes.
** Presumably they mean KiB.

8
  • Firstly, thank you for your help. But It does not directly relate to my question.
    – John
    Jun 19, 2020 at 11:56
  • @John you are welcome. Could you be more specific in your question? What exactly are you looking for? This explains why there is free space even when you get a memory page error.
    – tukan
    Jun 19, 2020 at 13:49
  • This answer is also helpful to me indeed. I am grateful to you. You see, the kernel complains when allocating memory with the size of order:10(i.e.page allocation failure: order:10). But there are free blocks indeed(i.e. "58*4096kB (C)" ). So I think it should not complain since there are enough free memory indeed.
    – John
    Jun 19, 2020 at 15:14
  • @John well your allocation fails due to the nature of the request for the memory allocator. See my edit, which should explain it in greater detail.
    – tukan
    Jun 19, 2020 at 19:09
  • 1
    @John You can't find that in the code. You will find it in the Linux Kernel book as I have suggested. I have added link to the answer.
    – tukan
    Jun 21, 2020 at 7:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .