图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

目录

  • HugeTLB Memory With PageFault

    • HugeTLB Memory: R/W 缺页场景

    • HugeTLB Memory: WP 缺页场景

    • HugeTLB Memory: COW 缺页场景

    • HugeTLB Memory: 不同粒度 HugeTLB 缺页场景

    • HugeTLB Memory: SYSV 缺页场景

    • HugeTLB Memory: POSIX 缺页场景

    • HugeTLB Memory: MEMFD 缺页场景

    • HugeTLB Memory: MCE(UE) 故障缺页场景

    • HugeTLB Memory: OOM 大页内存不足缺页场景

    • HugeTLB Memory: Surplus 超发大页缺页场景

图片无法显示,请右键点击新窗口打开图片


HugeTLB Memory With PageFault

图片无法显示,请右键点击新窗口打开图片

在 Linux 里,用户进程可以使用 malloc/mmap 分配虚拟内存,通常情况下虚拟内存最终映射到 4KiB 的物理内存上. 用户进程的虚拟内存除了可以映射 4KiB 的物理内存,其也可以映射更大粒度的物理大页,映射大页的好处简单来说就是节省页表内存开销和减少 TLB Entry 占用,从而降低内存峰值带来的性能损耗。目前 Linux 支持用户空间虚拟内存映射 2MiB/1Gig 物理大页的方法有:

  • 透明大页方案: 可以自动、无需修改应用程序代码的情况下,将零散的 4KiB 物理页映射迁移合并成 2MiB 物理页映射, 减少 TLB 缺失从而提供应用程序和系统的整体性能.
  • PMDMAPPED PFNMAP 方案: 在驱动模块的支持下,应用程序将虚拟内存直接映射到 2MiB 的系统预留物理内存上,优点是应用自我内存管理,减少 TLB 缺失.
  • HUGETLB 方案: 系统提供的大页池化机制,应用程序可以从大页池子中获得 2MiB/1Gig 物理页,然后将进程虚拟内存映射到 HugeTLB 大页上,核心优点就是减少 TLB 缺失.
  • 共享大页内存方案: 多个进程在使用共享内存时,可以采用共享内存大页,这样有利于减少 TLB 缺失和内存消耗.
  • HUGE-DAX 方案: 在支持 PMEM 的系统里,用户进程可以将虚拟内存直接映射到 2MiB 区域的 PMEM 内存上,同样可以减少 TLB 缺失.

图片无法显示,请右键点击新窗口打开图片

虽然系统支持多种应用程序虚拟内存映射 2MiB 物理内存的方案,有的是针对特定场景,而有的是需要过多的前置条件,但对于 HugeTLB 机制来说,其具有普适性,可以应用到很多场景,并且可以做到对应用程序透明. HugeTLB 机制将物理大页维持在内存池内,内存池和系统管理的物理内存是相互独立的,也就是说 HugeTLB 机制可以控制的内存池子的伸缩,另外系统在通用内存的分配和回收时,内存池子的内存不受影响。HugeTLB 机制默认建立两个公共的大页内存池子,其也支持基于 Hugetlbfs 文件系统建立 N 个私有的大页内存池子,最后应用程序可以从指定的大页池子中分配映射 2MiB/1Gig 的物理大页.

图片无法显示,请右键点击新窗口打开图片

HugeTLB 大页池子使用 STRUCT hstate 数据结构进行维护,其成员记录了某种粒度 HugeTLB 大页的使用情况,并维护了两类链表,其中一个链表维护了已经分配出去的 HugeTLB 大页,另外一类链表是为每个 NUMA NODE 维护的没有使用的 HugeTLB 大页。HugeTLB 大页存在多种状态,分别是: 空闲状态(HugePages_Free)预留状态(HugePages_Rsvd)超发状态(HugePages_Surp) 以及激活状态(Active).

图片无法显示,请右键点击新窗口打开图片

HugeTLB 大页池子使用不同的成员统计大页内存的使用情况,这些统计量让系统知道 HugeTLB 池子里大页使用情况, 并且各成员之间存在如下关系:

  • nr_huge_pages: 该成员用于指明在指定粒度的大页内存池子中总共包含大页的数量
  • max_huge_pages: 该成员用于指明指定粒度大页内存池子中固定大页的数量, 所谓固定大页就是一次性从系统中分配,并一直维护在大页内存池子中,不会被动态释放会系统的大页.
  • free_huge_pages: 该成员用于表示指定粒度大页内存池子中空闲大页的数量,空闲但不代表可用(可能被预留)
  • resv_huge_page: 该成员用于表示指定粒度大页内存池子中预留池子的大页数量, 预留表示已经分配但未被真正使用的大页
  • nr_overcommit_huge_pages: 该成员用于指明指定粒度大页能可以超发大页的数量,即最多可以从系统动态申请大页的数量
  • suplus_huge_pages: 该成员用于表示指定粒度大页内存池子中通过超发机制动态分配的大页数量

图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

图片无法显示,请右键点击新窗口打开图片