【问题标题】:Why Linux Kernel ZONE_NORMAL is limited to 896 MB?为什么 Linux Kernel ZONE_NORMAL 限制为 896 MB?
【发布时间】:2011-11-24 05:59:45
【问题描述】:

一个新手问题。我正在做一些内核研究并对 ZONE_NORMAL 的大小限制为 896MB。我不明白为什么内核不能 直接将4G物理内存映射到内核空间。一些文件 提到了它的页面映射大小限制。但是考虑到4G内存 有 2^20 页,每个“结构页”是 4 个字节,mem_map 将 只有4MB。那不应该是问题。希望你能给我一些 光。

谢谢

【问题讨论】:

  • 除了其他人在答案中提到的之外,我已经读到 896 MiB 限制在内核配置时是可调整的(在 Linux 设备驱动程序第 3 版中)

标签: linux kernel


【解决方案1】:

当然,内核可以映射所有可用内存。

在 Linux 中,所有 bank 中可用的内存被分类为“节点”。这些节点用于指示每个 bank 有多少内存。每个节点中的内存被划分为“区域”。当前定义的区域是ZONE_DMAZONE_NORMALZONE_HIGHMEM

ZONE_DMA 被某些设备用于数据传输,并映射到较低的物理内存范围(最大 16 MB)。

ZONE_NORMAL 区域中的内存被内核映射到线性地址空间的上部区域。大多数操作只能在ZONE_NORMAL进行;所以这是最关键的性能区域。 ZONE_NORMAL 从 16 MB 变为 896 MB。

为什么?

部分内存是为内核数据结构保留的,这些数据结构存储有关内存映射和页表的信息。这在 x86 上是 128 MB。因此,在内核可以访问的 1 GB 物理内存中(在典型配置中,为内核保留 1 GB),保留了 128 MB。因此,这 128 MB 中的内核虚拟地址不会直接映射到物理内存。这会为ZONE_NORMAL 留下最多 896 MB 的空间。因此,即使有 1 GB 的物理 RAM,实际上也只有 896 MB 可用于用户空间。

为了更好地理解这个主题,我建议你看一下 Linux 设备驱动程序 (pdf) 的第 15 章。

【讨论】:

  • 谢谢迈克尔。据我了解,内核虚拟地址只能直接映射896MB物理RAM。根据我的问题,为什么用户看不到 896MB-4GMB 物理内存。无论如何,内核空间能够容纳代表 4GB 物理内存的所有 2^20 页。它应该能够为用户空间进程分配一些高内存页面。谢谢
【解决方案2】:

内核将自身限制为 896 MB 的原因是出于性能原因。

内核可用的空间越多意味着用户空间可用的地址空间更少。这种 3/1 拆分意味着用户进程可以分配的最大地址空间为 3 GB——当然,由于内存碎片,实际上它似乎开始在 2.5 GB 左右出现故障。

可以使用不同的拆分:2/2 和 1/3 拆分为内核分配 2 GB 的地址空间,为用户空间分配 2 GB 的地址空间,为内核分配 3 GB 的地址空间,为用户空间分配 1 GB 的地址空间。 (这个firefox现在消耗了 1249 兆字节,所以它不适合那些 1/3 拆分内核之一。)

有一些内核(可能仅限供应商?)支持所谓的 4:4 分割——内核有 4 GB 的地址空间,用户空间有 4 GB 的地址空间。这些对于具有 32 或 64 GB 内存的 32 位系统非常有用——因为大型系统可能有许多磁盘、大量 IO 正在运行,并且需要大量缓冲块设备和网络流量。但是,这些 4:4 内核需要在进入和退出每个系统调用时刷新 TLB 缓存。这些 TLB 刷新会显着降低“小型”系统的速度,并且仅在额外内存可以缓存足够的磁盘/网络资源以提高系统性能的“大型”系统上才值得。

其他拆分不会导致此 TLB 刷新,因为 TLB 维护一个权限位,指示当 CPU 处于用户状态或主管状态时页面是否可用:内核页面始终被映射,但仅在CPU 的主管标志已设置。因此,当退出回到进入内核的进程时,进入和退出内核很快。上下文切换时,当然需要刷新TLB。

【讨论】:

  • 嗨,萨诺德:谢谢你的回答。我的问题是:给定 4GB 物理内存,为什么我们不能直接访问更高的 3GB 物理内存(ZONE_HIGHMEM)?即使考虑到内核虚拟空间只有 1GB,它仍然足够容纳所有页面文件。作为参考,这个document italic bold code Page 48 说它的页面地图问题。我不明白他计算 mem_map 的方式。希望你能给我一些启示。
  • 内核甚至不需要添加到内核入口的映射页表中——那些内核页总是在那里,只是它们的 PTE 设置了用户/主管位来指示它们'只能在主管模式下访问。
  • @caf:那意味着返回到同一个进程不会导致刷新,对吧?
  • 我当然不能像梅尔那样解释它;检查第 131 页:对于映射页面,在 PKMap 区域的开头存储了一个 PTE 页面集,以允许使用函数 kmap() 将 1024 个高页面短时间映射到低内存并使用 @ 取消映射987654325@。池似乎很小,但页面仅由kmap() 映射非常很短的时间。
  • @sarnold:我相信是这样(或另一个具有相同mm 的进程,即另一个线程)。
猜你喜欢
  • 2014-02-10
  • 1970-01-01
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
相关资源
最近更新 更多