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

标签 linux memory kernel

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

根据makelinux

The maximum allowed value for order is 10 or 11 (corresponding to 1024 or 2048 pages), depending on the architecture. The chances of an order-10 allocation succeeding on anything other than a freshly booted system with a lot of memory are small, however.

为什么会这样?我系统中的每一页为 4KB(4096 字节),2^10 页 = 1024 页,总大小为 1024*4096 = 4 194 304(字节)~4MB。它只有 4MB 的连续空间,内核非常小:vmlinuz 只有 2.1MB,initrd 是 15MB。整个内核的总内存消耗约为 300MB。内核分配 4MB 的连续页面必须绰绰有余。即使在具有 1GB/3GB 内核/用户的普通机器上,也确保内核不会用完整个 1GB。但是只有 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

最佳答案

如果我没记错的话,__get_free_pages 使用 buddy allocation ,它不仅确实将其分配分散在整个物理内存中,而且它以最坏的可能模式这样做,以便随后尝试分配大的连续 block 。如果我的计算是正确的,那么在您的系统上具有 24GB 的物理 RAM,即使除了伙伴分配之外没有任何空间被占用,渲染也将花费少于 8192 次 0 (4KB) 分配用 __get_free_pages 分配 4MB block 是不可能的。

有一种东西叫做 contiguous memory allocator ,这应该解决设备驱动程序对大量物理连续分配的真正需求;截至 2011 年 6 月,它不在官方内核中,但那是一年多以前的事了。你应该调查一下。

关于linux - 为什么使用 __get_free_pages() 以 10 或 11 的顺序分配页面通常会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11340475/

相关文章:

Java JDBC clearBatch() 和堆内存

linux - 如何从内核写入只读文件?

linux - 从内核模块读取原始性能计数器

C 内核字符串连接和比较

linux - 如何使用Linux命令将 '1.jpg'等文件夹的所有文件重命名为 '1 hello.jpg'?

Linux 内核 : CMA & Device Tree

linux - 为什么我在 ubuntu 上安装的文件系统上得到不正确的时间戳?

c - 如果 bool 是 int 的宏,为什么它的大小不同?

android -/dev/mem 和/dev/kmem 不存在?

memory - Go:重用映射键时会占用大量内存