大页相关
Transparent Huge Page (THP)
THP 是一个软件上的概念:Transparent Huge Pages (THP) is a Linux memory management system that reduces the overhead of Translation Lookaside Buffer (TLB) lookups on machines with large amounts of memory by using larger memory pages.
为什么叫做 Transparent?
Huge pages can be difficult to manage manually, and often require significant changes to code in order to be used effectively. As such, Red Hat Enterprise Linux 6 also implemented the use of transparent huge pages (THP). THP is an abstraction layer that automates most aspects of creating, managing, and using huge pages. 因为 THP 是 RedHat 提出来的为了让大页使用更加易用的一个框架,所以叫透明大页:
THP are named as such because the allocation and management of these large pages are transparent to the applications running on the system. THP hides much of the complexity in using huge pages from system administrators and developers.
使用者不感知使用的是大页还是基础页。透明大页的实现原理也比较简单,通过内核任务“khugepaged”,不断扫描进程的 VMA 虚拟内存块,判断连续 2M 的空间是否满足转换成大页的条件,如果满足则将这些物理内存合并成一个大页。
THP 有三种模式:always, madvise, never。一些小页会不会合并成大页,需要有两重检查:
- 当条件满足时,这块区域是否允许合并成大页?这些是上面三个参数控制的。
always表示所有区域都允许、madvise表示只有通过madvise指定的区域允许、never表示不开启; - 这块区域小页是否能够合成一个大页?这批虚拟地址连续的小页(或者说虚拟地址空间)所映射到的物理地址空间,是否也是连续的?
因此可以忽略透明,直接称为大页。
- Application unaware: Applications don't need to explicitly request or be aware of THP allocation. The operating system kernel handles the process of identifying suitable memory regions and converting them into THPs.
- Memory management abstraction: THP provides a layer of abstraction between the application's virtual memory addresses and the physical memory layout. Applications continue to use their regular virtual memory addresses, while the kernel manages the mapping to the larger THP physical pages in the background.(也就是说 VA 都是连续的,但是 back VA 的那些才是 huge page)。
- No code changes required: Applications don't need code modifications to benefit from THP. The kernel automatically manages the mapping and translation between virtual and physical addresses.
THP 需要硬件对于大页的支持吗?
需要页表支持 set PS 位。如果开始用了大页,那么很明显,一个 non-4K 级的 PSE 可能是 leaf(一个大页),也可能是 non-leaf(下面管着很多小页), 那怎么区分一个页表项是否为 leaf 呢?通过 PS 位标志。
硬件上的大页 / Page Size / 大页和 4 级 5 级页表的区别
在 64 位的硬件中,也即 IA-32e 架构下,可以支持 4 级或者 5 级的分页模型。
这时页表查找路径是 PML5E --> PML4E --> PDPTE --> PDE --> PTE。
- 当 PDE 不可用时(PDPTE 的 PS 标志是 1),那么虚拟地址 29:0 位用于页内偏移,所以页框的大小是 1GB;
- 如果 PDE 可用但 PTE 不可用时,也是同样的 PS 标志是 1,虚拟地址 20:0 位用于页内偏移,所以页框的大小是 2MB;
- 如果 PTE 可用,那么页框大小就是 4KB。
所以,如果某个页表项的 PS 标志是 1,则表示只需要翻译到该层级的页表即可,在 x86 中,Linux 对大页的支持:
// 2M 或 4M 大页
static inline pte_t pte_mkhuge(pte_t pte)
{
return pte_set_flags(pte, _PAGE_PSE);
}
// 1G 大页
static inline pmd_t pmd_mkhuge(pmd_t pmd)
{
return pmd_set_flags(pmd, _PAGE_PSE);
}
如果简简单单置上 PS bit 就可以是大页,那么 4 级和 5 级页表的作用是什么?
主要是可以支持更大内存了:4 级页表已经可以支持 256TB 的了,其实是用不完的,所以目前我们又处于 4 级普遍使用,5 级需要展望的尴尬时刻。
(45 封私信 / 16 条消息) 深入理解Linux内存管理(九)大页 - 知乎
除了 Page Table,EPT Page Table 支持 PS bit 来设定 EPT 大页吗?
有,bit 7 就是。
THP 内核代码
enabled 注册:
hugepage_init
hugepage_init_sysfs
// 添加 /sys/kernel/mm/transparent_hugepage/ 目录
// transparent_hugepage 的 parent 是 mm_kobj,也就是 mm 目录
*hugepage_kobj = kobject_create_and_add("transparent_hugepage", mm_kobj);
// 添加 enabled 选项
err = sysfs_create_group(*hugepage_kobj, &hugepage_attr_group);
触发写 enabled:
enabled_store
if (sysfs_streq(buf, "always"))
clear_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG, &transparent_hugepage_flags);
set_bit(TRANSPARENT_HUGEPAGE_FLAG, &transparent_hugepage_flags);
在分配 folio 时根据 bit 选择 order 并保存:
alloc_anon_folio
orders = thp_vma_alloable_orders()
hugepage_global_always
return transparent_hugepage_flags & ((1<<TRANSPARENT_HUGEPAGE_FLAG) | (1<<TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG));
KVM 感知 host THP 信息:
__kvm_mmu_max_mapping_level
// 这个函数就是走一下 host 上的页表,找到这个 pfn backed 的那个 hva 所对应的页需要几级页表
host_pfn_mapping_level
if (pud_leaf(pud))
level = PG_LEVEL_1G;
if (pmd_leaf(pmd))
level = PG_LEVEL_2M;
//...
THP 性能收益模型分析
- TLB 命中率提升:因为我们需要的页表项更少了,所以 TLB 空间相对来说就更充裕了,TLB 命中率提升;
- TLB 未命中的情况下,使用了 THP 之后,硬件页表层级肯定更少,比如以前是五级页表,现在合并大页之后只需要四级页表,那么我们硬件地址翻译的次数就更少了。
- Page fault 次数更少了:当内存访问没有局部性时,简单计算可以得出概率都是一样的。但是因为现实是内存访问有局部性,从一个 4K 页访问到临近 4K 页时可能会发生 page fault,但是如果我们是在 2M 大页中,就不会发生 page fault,因为上一次 page fault 已经一次性把整个 2M 页放进来了(大页情况内存布局更整,而 4K 更碎片化)。
- 内核软件层:批量 PTE 以及 RMAP 操作、减少 LRU 扫描成本。
THP and memory folios
THP (Transparent Huge Pages):
- Focuses on reducing memory overhead by using larger page sizes for memory allocations.
- By using larger pages (e.g., 2MB or 1GB instead of the usual 4KB pages), THP reduces the number of page table entries required to manage memory, leading to potentially better performance and lower memory management overhead.
Memory Folios:
- Focuses on optimizing memory management for guest virtual machines (VMs) running on a Linux host.
- Introduced in newer Linux versions, memory folios are essentially contiguous regions of physical memory allocated to a VM.
- They improve efficiency by reducing page table fragmentation within the guest VM and simplifying the translation between guest virtual addresses and host physical addresses.
虚拟化环境下的 THP
| Host THP | EPT 大页 | Guest THP | 能否运行 | 备注 |
|---|---|---|---|---|
| 0 | 0 | 0 | 能 | 最基本最正常的情况 |
| 0 | 0 | 1 | 能 | 可以,就是一个 Guest Physical 大页被多个小页而 back |
| 0 | 1 | 0 | 不能 | QEMU 申请的如果是很多个小页(这些小页是物理上不连续的),那么 KVM 没有办法使用大页 EPT 映射到大页上,因为他们够不成物理上连续的一个大页。 |
| 0 | 1 | 1 | 不能 | 同上 |
| 1 | 0 | 0 | 能 | 能翻译,只不过多一级 EPT 翻译,以及 guest 页表多一级翻译有点浪费。 |
| 1 | 0 | 1 | 能 | Guest 页表可以有加速,但是 EPT 没有用到加速。 |
| 1 | 1 | 0 | 能 | Guest 页表有浪费 |
| 1 | 1 | 1 | 能 | 性能最优,都没有浪费 |
所以结论就是:Host 和 Guest 同时开大页才能让性能最优:
当访客大页得到主机大页的支持时,称为对齐大页,可以充分发挥大页性能。当访客大页和主机大页未对齐时,称为错位大页,此问题可使性能降低 67%。
([[gemini.pdf#page=2&selection=32,0,47,52&color=annotate|gemini, p.2]]) Though there are system components coalescing base pages into huge pages at both the guest and the host layers, because they coalesce pages independently, it is likely that a huge page formed in the guest is not backed by a huge page in the host, or vice versa. In these cases, the huge pages can hardly reduce address translation overhead. We refer to these huge pages as mis-aligned huge pages and refer to this problem as huge page misalignment problem. This problem can degrade performance by up to 67% as shown in §6.
(45 封私信 / 22 条消息) Making Dynamic Page Coalescing Effective on Virtualized Clouds——论文泛读 - 知乎
论文这里也可以印证:
([[gemini.pdf#page=3&selection=134,0,137,17&color=annotate|gemini, p.3]]) Using huge pages can reduce TLB misses only when both the guest and the host use huge pages for the same data, i.e., a huge GVP is backed by a huge GPP and a huge HPP at the same time.
下面这个图很直观(可见如果 mis-aligned,可能性能还不如都不开启大页):
| ![[gemini.pdf#page=4&rect=34,597,316,723&color=annotate | gemini, p.4]] |
单开反而可能会导致性能下降的原因概括起来是:
([[gemini.pdf#page=4&selection=112,0,113,45&color=annotate|gemini, p.4]]) Though the misaligned huge pages still can help reduce page walk overhead, they increase TLB misses.
那么为什么 TLB miss 会增加呢?
主要原因是如果 mis-aligned TLB 没有办法 Cache,具体原因分析放在下面不同情况的章节 [[#仅仅 Guest 开启 THP 的情况]], [[#仅仅 Host 开启 THP 的情况]]。
Guest 的 THP 和 Host 的 THP 是绑定的关系吗?
不是,虽然 host 和 guest 共用一个物理 MMU,但其实都是四级页表。host 页表的 PS 可以置上以使用大页,guest 页表的 PS 完全可以不置上使用小页。一块物理内存上的 2M 地址空间,完全可以在 host 上来看是连续的但是从 guest 角度来看是离散的。
当 Host kernel enable THP 之后,Host KVM 的 EPT 也会置上对应位来减少一级地址转换:
在开启 THP 的宿主机上运行 KVM 虚拟机时,EPT 的层级通常也会减少一级。这是一个常见的优化行为,代码逻辑请看 [[#THP 内核代码]]。
如果宿主机上开了 THP,那么宿主机一个内存页就变成了 2M/1G 大小,那么 EPT 也没有必要还是映射到 4K 的区间了,因为 QEMU/KVM 维护的是 HVA <-> GPA 的映射,也就是 QEMU 需要先申请一段虚拟地址连续的内存空间,对应的物理地址是大页,那么 KVM 没有必要给 EPT 多塞一级页表,没有意义。
默认情况下,EPT 和 Paging 都是四级页表。
如果 guest enable 了 THP,那么 EPT 页表会使用大页模式吗,还是仅仅 guest 页表会使用大页模式?
- Guest THP off, Host THP off: (4 + 1) 4 + 4 = 24 次
- Guest THP off, Host THP on: (4 + 1) 3 + 4 = 19 次
- Guest THP on, Host THP on: (3 + 1) 3 + 3 = 15 次.
https://k48xz7gzkw.feishu.cn/docx/ZFsJdhCzuoKSIUxI0u8cFGk2nMg#share-Orz4drsvjoA4wCxX54sc3aUInEc
仅仅 Guest 开启 THP 的情况
是支持且合理的:
https://k48xz7gzkw.feishu.cn/docx/ZFsJdhCzuoKSIUxI0u8cFGk2nMg#share-IhTzd5O92oEybGxdwmqcUQ9vnQg
只不过只有 Guest 页表翻译能够少一级,EPT 页表没有办法再少一级。同时 TLB 无法缓存了(PSC 还能缓存吗?)。
如果 host 没有开 THP 但是 guest 开了:最终从 GVN 到 HPN 的翻译没有办法 cache 到 TLB 里面。
原因很简单,因为 TLB 里存的都是页号的映射,我们没有办法从一个大页映射到一小大页上。
([[gemini.pdf#page=3&selection=142,3,145,53&color=annotate|gemini, p.3]]) When a huge GVP is backed by multiple base HPPs in the host, there is not a PTE in the VM page table that corresponds to the GVP; thus, no PTEs can be loaded to the TLB to help translation.
仅仅 Host 开启 THP 的情况
- 从 Guest 页表来看,这是一个小页
- 从 EPT 页表来看,这是一个大页。
是支持且合理的,只不过只有 EPT 页表
([[gemini.pdf#page=3&selection=145,54,149,24&color=annotate|gemini, p.3]]) If a base GVP is backed by a huge HPP, because there is not a PTE in the VM page table that corresponds to the virtual page, the page offset cannot be used to obtain correct host physical address (HPA).
这种情况:从 GVN 到 HPN 的翻译没有办法 cache 到 TLB 里面。
原因很简单,因为 TLB 里存的都是页号的映射,我们没有办法从一个大页映射到一小大页上。
THP 使用实操
更改 THP 的使能情况并不需要重启机器,可以实时动态进行配置。
# 检查
cat /sys/kernel/mm/transparent_hugepage/enabled
# 表示是 never
always madvise [never]
# 使能(申请的任何内存页都是大页)
echo always > /sys/kernel/mm/transparent_hugepage/enabled
# 尽量(根据应用自己需求来,如果应用希望是大页,那么就使用大页,否则使用小页)
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
# 关闭,很好理解
echo never > /sys/kernel/mm/transparent_hugepage/enabled
HugeTLB
需要硬件支持多个不同的页大小才行。For example, x86 CPUs normally support 4K and 2M (1G if architecturally supported) page sizes.
First the Linux kernel needs to be built with the CONFIG_HUGETLBFS (present under “File systems”) and CONFIG_HUGETLB_PAGE (selected automatically when CONFIG_HUGETLBFS is selected) configuration options.
The 'hugetlb" term is also (and mostly) used synonymously with a HugePage, 所以说其实 HugeTLB 就是标准大页,后面 RH 为了增加大页分配的灵活性,引入了 THP,更加灵活也更加复杂。
Hugetlbfs
Applications can allocate memory from hugetlbfs and benefit from potential performance improvements.
主要是把 huge page 这个 feature 暴露给 application 来用。application 可以在这个 fs 下面创建文件,其实是 backed by memory 里的 huge page 的。
The method to use hugetlbfs basically boils down to:
- use mmap with MAP_HUGETLB flag;
- or, map a file from the mounted hugetlb filesystem, if it exists.
复合页, HugeTLB, THP 三者区别 / 大页
可以说 THP 是对 HugeTLB / HugePage 的一个升级。
此三者基本都有一个特点,就是都属于多 page 组合而成,所以他们都能称之为复合页。
Linux 下的大页分为两种类型:标准大页(Huge Pages)和透明大页(Transparent Huge Pages)。Huge Pages 有时候也翻译成大页/标准大页/传统大页。
THP 是 RHEL 6 开始引入的一个功能。
这两者的区别在于大页的分配机制,标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。
Redhat 的文档,谈了 Huge page 以及 Transparent huge page:5.2. Huge Pages and Transparent Huge Pages Red Hat Enterprise Linux 6 | Red Hat Customer Portal
传统大页很难手动管理,而且通常需要对代码进行重大更改才能有效地使用。因此,红帽实现引入了透明大页面 (THP)。THP 是一个抽象层,可以自动创建、管理和使用传统大页的大多数方面。
The HugeTLB term is also (and mostly) used synonymously with a HugePage.
THP is a much more complex mechanism than HugeTLB. 更复杂更灵活。
hugetlb: This is an entry in the TLB that points to a HugePage (a large/big page larger than regular 4K and predefined in size). HugePages are implemented via hugetlb entries, i.e. we can say that a HugePage is handled by a "hugetlb page entry". The 'hugetlb" term is also (and mostly) used synonymously with a HugePage (See Note 261889.1). In this document the term "HugePage" is going to be used but keep in mind that mostly "hugetlb" refers to the same concept.