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

2024-03-13

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

根据制作linux http://www.makelinux.net/ldd3/chp-8-sect-3

order 的最大允许值为 10 或 11(对应于 1024 或 2048 页),具体取决于架构。的机会 order-10 分配在除新启动的系统之外的任何系统上均成功 然而,具有大量内存的系统却很小。

为什么会这样?我的系统中每个页面为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 uses 好友分配 http://en.wikipedia.org/wiki/Buddy_allocation,这不仅does将其分配分散在整个物理内存中,它是在最坏的可能后续尝试分配大的连续块的模式。如果我的计算正确的话,在你的物理 RAM 为 24GB 的系统上,even if除了伙伴分配之外,没有任何空间被任何东西占用,因此需要不到 8192 个 order-0 (4KB) 分配来渲染 4MB 块的分配__get_free_pages不可能的。

有一种东西叫做连续内存分配器 http://lwn.net/Articles/447405/,它应该解决设备驱动程序对大量物理连续分配的真正需求;截至 2011 年 6 月,它还没有出现在官方内核中,但那已经是一年多前的事了。你应该调查一下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么使用 __get_free_pages() 进行顺序为 10 或 11 的页面分配通常会失败? 的相关文章

  • 如何从 Linux 和 Solaris 上的挂载中提取 NFS 信息?

    我需要使用提取 NFS 挂载信息mount在 Linux RHEL 4 5 和 Solaris Solaris 10 系统上 由于这是 SSH 命令的一部分 因此提取需要在一行中进行 不幸的是 Linux 和 Solaris 在该行的不同部
  • 在 Mac OS X 中创建虚拟 USB 设备

    我尝试以编程方式在 Mac OS 中添加带有驱动程序的虚拟 USB 设备 IOKit 文档说 传统上 虚拟设备的驱动程序在 IOResources 上匹配 因为虚拟设备不发布自己的 nub 此类驱动程序的另一个示例是 HelloIOKit
  • 如何获取子进程的返回值?

    程序计算从 1 到 N 的数字之和 子进程计算偶数之和 父进程计算奇数之和 我想在父进程中获取子进程的返回值 我怎么做 include
  • 如何从纯文本中查找键值存储中的值

    给定一个纯文本文件 其中包含 FOO foo BAR bar BAZ baz 我们如何grep使用键获取值 Use a 向后看 https regex101 com r q3FNpe 1 grep Po lt FOO w file foo
  • 执行bash脚本时如何显示行号

    我有一个测试脚本 其中有很多命令并将生成大量输出 我使用set x or set v and set e 因此当发生错误时脚本将停止 但我还是很难定位到哪一行执行停止了 从而定位问题所在 有没有一种方法可以在每行执行之前输出脚本的行号 或者
  • Linux C 如何打开目录并获取文件描述符

    include
  • 执行 grails/groovy 时,Linux 上没有可用的控制台输出

    当执行 groovy 脚本或 grails 应用程序时 没有可用的输出 输入 gt 只有一个清晰的控制台屏幕 即使不启动 X Window System 输出也是不可见的 我也尝试过 grailscompile plain output 也
  • 使用 M1 在 dockerized Linux 上安装节点画布

    我有以下Dockerfile我在 MacBook Air M1 上运行 所以在 docker 中我有带有 M1 的 linux FROM node 16 7 0 WORKDIR work CMD while true do sleep 10
  • Docker 无法写入使用 -v 挂载的目录,除非它有 777 权限

    我正在使用docker solr https github com makuk66 docker solr使用 docker 生成图像 我需要在其中安装一个目录 这是我使用 v flag 问题是容器需要写入我已安装到其中的目录 但似乎没有权
  • 删除损坏的链接 Unix

    我想删除损坏的链接 但在此之前我想确认目录中是否存在链接文件 我们来调用一下链接A if a A then print ya A is ther fi But if A链接已损坏 那么我该如何检查 find L type l找到损坏的符号链
  • 与 grep 类似地突出显示文本,但不过滤掉文本[重复]

    这个问题在这里已经有答案了 使用 grep 时 它将突出显示与正则表达式匹配的行中的任何文本 如果我想要这种行为 但同时让 grep 打印出所有行怎么办 快速浏览完 grep 手册页后 我发现一无所获 使用确认 看看它的 passthru此
  • find 命令的“exec”功能可以在后台启动程序吗?

    我想做这样的事情 find iname Advanced Linux Program exec kpdf 可能的 还有其他类似的方法吗 首先 它不会像你输入的那样工作 因为 shell 会将其解释为 find iname Advanced
  • 如何在 Docker 容器中运行 Nginx 而不停止?

    我在 Docker 容器上安装了 Nginx 并尝试像这样运行它 docker run i t p 80 80 mydockerimage usr sbin nginx 问题是 Nginx 的工作方式是 初始进程立即生成一个 Nginx 主
  • 在 Linux 上的 makefile 和 Makefile 之间进行选择

    我想在一个目录中同时使用 Makefile 和 makefile 进行 make 默认情况下 它将执行makefile 我可以选择执行 Makefile 吗 提前致谢 最简单的选择是使用 f make f Makefile From man
  • 如何使用AWK从文件中连续输出行

    我有一个多行文件 我想连续输出文件的某些行 比如第一次 从第1行打印到第5行 下次 打印第2行到第6行 依此类推 我发现 AWK 是一个非常有用的函数 我尝试自己编写代码 但它什么也没输出 以下是我的代码 bin bash for n in
  • 堆内存和Slab分配

    我很困惑heap and free list 我有几个问题 我对C中malloc的工作原理有自己的理解 如果我错了 请纠正我 堆内存是否被组织为数据的链表 空闲列表 块 堆内存和空闲列表有区别吗 我对存储分配的理解 有待改进 当我们调用ma
  • 专门逐行调试

    我有一个用 Pascal 编写的脚本 我会以这种方式调试它 在每一行停止 转储内存中所有变量的值 然后转到下一行 是否可以使用 gdb 或其他 Linux 开源工具来完成此操作 使用选项编译文件 g fpc gpc g file pas R
  • 让子进程等待直到收到父进程的信号

    我想从父级创建 N 个子级 我希望所有的孩子同时开始 一个功能 测量时间 因此 我将该函数放入信号处理程序中 当父级完成创建 分叉 所有子级时 它会向所有子级发送信号 使用kill children id 以让 make 开始 代码如下 但
  • 如何在 C++ 中检查文件是否已被另一个应用程序打开?

    我知道 有is open C 中的函数 但我希望一个程序检查文件是否尚未被另一个应用程序打开 有没有办法使用标准库来做到这一点 编辑 在答案中澄清这是针对 Linux 应用程序的 不仅标准库没有这个功能 一般来说也是不可能的 你可以 在li
  • 如何检查程序是否在 Windows 上的 Ubuntu 上的 Bash 中运行,而不仅仅是普通的 Ubuntu?

    非常简单 确定您所使用的操作系统的通常位置似乎与 Ubuntu for Windows 上的普通 Ubuntu 相同 例如uname a与本机 GNU Linux 安装相同并且 etc os version与 Ubuntu Trusty T

随机推荐