为什么使用__get_free_pages()以10或11的顺序分配页面通常会失败?

Amu*_*umu 8 linux memory kernel

我的系统内存很多(一台24GB的服务器).在我的系统中,内核空间为崩溃内核分配了320MB和120MB.内存的其余部分用于其他目的.但是,当我用于__get_free_pages()分配顺序为11的连续页面时,内核无法分配2 ^ 10页.为什么?

根据makelinux

订单的最大允许值为10或11(对应于1024或2048页),具体取决于体系结构.然而,除了具有大量内存的新引导系统之外,订单10分配成功的可能性很小.

为什么会这样?我系统中的每个页面是4KB(4096字节),2 ^ 10页= 1024页,总大小是1024*4096 = 4 194 304(字节)~4MB.它只有4MB的连续空间,内核非常小:vmlinuz只有2.1MB而initrd是15MB.整个内核的总内存消耗约为300MB.内核必须绰绰有余地分配4MB的连续页面.即使在1GB/3GB内核/用户的普通机器上,也确保内核不会耗尽整个1 GB.但是,只有4MB连续页面的分配怎么可能失败呢?我认为,在内核空间中,内存不会分散在物理内存中(由于虚拟内存映射),而是线性且连续的.

我尝试首先加载我的内核模块,分配2 ^ 10页,但它失败并转储堆栈跟踪:

[    6.037056]  [<ffffffff810041ec>] dump_trace+0x86/0x2de
[    6.037063]  [<ffffffff8122fe83>] dump_stack+0x69/0x6f
[    6.037070]  [<ffffffff8108704e>] warn_alloc_failed+0x13f/0x151
[    6.037076]  [<ffffffff8108786a>] __alloc_pages_nodemask+0x80a/0x871
[    6.037081]  [<ffffffff81087959>] __get_free_pages+0x12/0x50
Run Code Online (Sandbox Code Playgroud)

zwo*_*wol 7

如果我没有记错,__get_free_pages使用哥们分配,这不仅不会在整个物理内存分散其分配,它在这样做最坏的可能以后尝试分配大的连续的块模式.如果我的计算是正确的,你的系统物理内存24GB的,即使没有空间任何被任何东西,但哥们分配占用,这将需要不到8192为了-0(4KB)的分配呈现一个4MB块的分配__get_free_pages不可能.

有一个称为连续内存分配器的东西,它应该解决设备驱动程序对大型物理连续分配的真正需求; 截至2011年6月,它不在官方内核中,但现在已经超过一年了.你应该研究一下.

  • 我的意思是,在发生了一些小数k(4096 <k <8192)的0次分配之后,将没有可以满足您的订单10请求的连续块.*你*没有做那些订单0分配,在你有机会之前运行的代码. (3认同)